非对称加密算法之ElGamal

来源:互联网 发布:直接上淘宝网 编辑:程序博客网 时间:2024/04/28 20:51
一.概述
  (1)ElGamal只支持“公钥加密、私钥解密”的过程
  (2)由BC提供支持,JDK暂未提供实现方法

二.加解密过程简析
  1.接收方A构建密钥对,公布公钥
  2.发送方B使用A公布的公钥加密数据
  3.接收方A使用私钥解密数据

三.CODE SHOW
public class TestElGamal {private static final String SCURITYTYPE = "ElGamal";//只提供公钥加密,私钥解密//JDK未提供实现,是由BC来实现的算法public static void main(String[] args) {String src = "ElGamal加密";bcElGamal(src);}public static void bcElGamal(String src){//加入对BouncyCastle支持  Security.addProvider(new BouncyCastleProvider());try {//1.初始化密钥AlgorithmParameterGenerator apg=AlgorithmParameterGenerator.getInstance(SCURITYTYPE);apg.init(256);  AlgorithmParameters params=apg.generateParameters();          DHParameterSpec dhParams=(DHParameterSpec)params.getParameterSpec(DHParameterSpec.class);          KeyPairGenerator kpg=KeyPairGenerator.getInstance(SCURITYTYPE) ;          kpg.initialize(dhParams,new SecureRandom());          KeyPair keyPair=kpg.generateKeyPair();          PublicKey publicKey= keyPair.getPublic();          PrivateKey privateKey= keyPair.getPrivate();          System.out.println("公钥串:"+Base64.encodeBase64String(publicKey.getEncoded()));        System.out.println("私钥串:"+Base64.encodeBase64String(privateKey.getEncoded()));                //2.公钥加密        X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(publicKey.getEncoded());            KeyFactory keyFactory = KeyFactory.getInstance(SCURITYTYPE);              PublicKey pubKey = keyFactory.generatePublic(x509EncodedKeySpec);            Cipher cipher = Cipher.getInstance(SCURITYTYPE);            cipher.init(Cipher.ENCRYPT_MODE, pubKey); //加密模式            byte[] result = cipher.doFinal(src.getBytes());            System.out.println("加密数据:"+Base64.encodeBase64String(result));                  //3.私钥解密        keyFactory=KeyFactory.getInstance(SCURITYTYPE);          PKCS8EncodedKeySpec pkcs8KeySpec=new PKCS8EncodedKeySpec(privateKey.getEncoded());          PrivateKey priteKey=keyFactory.generatePrivate(pkcs8KeySpec);          Cipher cipher2=Cipher.getInstance(keyFactory.getAlgorithm());          cipher2.init(Cipher.DECRYPT_MODE, priteKey);          byte[] resultData = cipher2.doFinal(result);          System.out.println("解密后的数据:"+new String(resultData));} catch (Exception e) {e.printStackTrace();}}}

四.输出结果


五.异常处理

Java几乎各种常用加密算法都能找到对应的实现。因为美国的出口限制,Sun通过权限文件(local_policy.jar、US_export_policy.jar)做了相应限制。因此存在一些问题:
1.密钥长度上不能满足需求(如:java.security.InvalidKeyException: Illegal key size or default parameters);
2.部分算法未能支持,如MD4、SHA-224等算法;
3.API使用起来还不是很方便;一些常用的进制转换辅助工具未能提供,如Base64编码转换、十六进制编码转换等工具。

Oracle在其官方网站上提供了无政策限制权限文件(Unlimited Strength Jurisdiction Policy Files),我们只需要将其部署在JRE环境中,就可以解决限制问题。
下载地址:
      1).Java 5.0 无政策限制文件
      2).Java 6 无政策限制文件
      3).Java 7 无政策限制文件
      4).其他版本 无政策限制文件

解压文件后,将其中的两个jar文件(local_policy.jar和US_export_policy.jar)拷贝至jdk安装路径%JDK_HOME%\jre\lib\security目录下。同时,有必要在%JRE_Home%\lib\security目录下,也需要对应覆盖这两个文件。
配置权限文件的最终目的是为了使应用在运行环境中获得相应的权限,可以加强应用的安全性。通常,我们在应用服务器上安装的是JRE,而不是JDK。因此,这就很有必要在应用服务器的%JRE_Home%\lib\security目录下,对应覆盖这两个权限文件。很多开发人员往往忽略了这一点,导致事故发生。



0 0