非对称加密算法(3):ElGamal

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_31301681/article/details/77914293

一.ElGamal:ElGamal算法,是一种较为常见的加密算法,它是基于1985年提出的公钥密码体制和椭圆曲线加密体系。既能用于数据加密也能用于数字签名,其安全性依赖于计算有限域上离散对数这一难题。在加密过程中,生成的密文长度是明文的两倍,且每次加密后都会在密文中生成一个随机数K,在密码中主要应用离散对数问题的几个性质:求解离散对数(可能)是困难的,而其逆运算指数运算可以应用平方-乘的方法有效地计算。


二.注意!!!

     加密时抛出java.security.InvalidKeyException: Illegal key size or default parameters

原因:Illegal key size or default parameters是指密钥长度是受限制的,java运行时环境读到的是受限的policy文件。文件位于${java_home}/jre/lib/security,这种限制是因为美国对软件出口的控制。

解决方案:替换 ${java_home}/jre/lib/security 的 local_policy.jar 和 US_export_policy.jar ,不同的jdk版本的替换文件不一致,具体参看下面的lian:

  JCE8: http://www.oracle.com/technetwork/java/javase/downloads/jce8-download-2133166.html

  JCE7: http://www.oracle.com/technetwork/java/embedded/embedded-se/downloads/jce-7-download-432124.html

  JCE6: http://www.oracle.com/technetwork/java/javase/downloads/jce-6-download-429243.html

扫描二维码关注公众号,回复: 3804467 查看本文章

  JCE5-1.4:http://www.oracle.com/technetwork/java/javasebusiness/downloads/java-archive-downloads-java-plat-419418.html#jce_policy-1.5.0-oth-JPR

三.具体的实现(java):

import java.security.AlgorithmParameterGenerator;  
import java.security.AlgorithmParameters;  
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.KeyFactory;  
import java.security.KeyPair;  
import java.security.KeyPairGenerator;  
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;  
import java.security.PublicKey;  
import java.security.SecureRandom;  
import java.security.Security;  
import java.security.spec.InvalidKeySpecException;
import java.security.spec.InvalidParameterSpecException;
import java.security.spec.PKCS8EncodedKeySpec;  
import java.security.spec.X509EncodedKeySpec;  

import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;  
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.spec.DHParameterSpec;  

import org.apache.commons.codec.binary.Base64;  
import org.bouncycastle.jce.provider.BouncyCastleProvider;  

public class ElGamal {

	public static void main(String[] args) throws Exception {
		
		String src = "欧阳草帽";
		KeyPair keyPair = getKeyPair();  
		//公钥
        PublicKey publicKey = getPublicKey(keyPair);  
        //私钥
        PrivateKey privateKey = getPrivateKey(keyPair); 

        byte[] publicKeyEnc = publicKey.getEncoded();
        byte[] privateKeyEnc = privateKey.getEncoded();
        System.out.println("秘钥 :"+Base64.encodeBase64String(privateKeyEnc));
		System.out.println("公钥 :"+Base64.encodeBase64String(publicKeyEnc));
        
		//加密数据 
		byte[] result = ensrypt(src, publicKeyEnc);  
        System.out.println("加密的数据 :"+Base64.encodeBase64String(result));
		
        result = decrypt(privateKeyEnc, result);
		System.out.println("解密数据:"+new String(result));
	}

	/**
	 * 解密数据 
	 * @param privateKeyEnc :私钥 
	 * @param result  : 解密数据 
	 * @return
	 * @throws NoSuchAlgorithmException
	 * @throws InvalidKeySpecException
	 * @throws NoSuchPaddingException
	 * @throws InvalidKeyException
	 * @throws IllegalBlockSizeException
	 * @throws BadPaddingException
	 */
	public static byte[] decrypt(byte[] privateKeyEnc, byte[] result)
			throws NoSuchAlgorithmException, InvalidKeySpecException,
			NoSuchPaddingException, InvalidKeyException,
			IllegalBlockSizeException, BadPaddingException {
		KeyFactory keyFactory = KeyFactory.getInstance("ElGamal");
		PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(privateKeyEnc);
		PrivateKey priKey = keyFactory.generatePrivate(pkcs8EncodedKeySpec);
		Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
		cipher.init(Cipher.DECRYPT_MODE, priKey);
		result = cipher.doFinal(result);
		return result;
	}

	/**
	 * 加密数据 
	 * @param src : 加密数据 
	 * @param publicKeyEnc : 公钥
	 * @return
	 * @throws NoSuchAlgorithmException
	 * @throws InvalidKeySpecException
	 * @throws NoSuchPaddingException
	 * @throws InvalidKeyException
	 * @throws IllegalBlockSizeException
	 * @throws BadPaddingException
	 */
	public static byte[] ensrypt(String src, byte[] publicKeyEnc)
			throws NoSuchAlgorithmException, InvalidKeySpecException,
			NoSuchPaddingException, InvalidKeyException,
			IllegalBlockSizeException, BadPaddingException {
		KeyFactory keyFactory=KeyFactory.getInstance("ElGamal");  
        //初始化公钥  
        //密钥材料转换  
        X509EncodedKeySpec x509KeySpec=new X509EncodedKeySpec(publicKeyEnc);  
        //产生公钥  
        PublicKey pubKey=keyFactory.generatePublic(x509KeySpec);  
        //数据加密  
        Cipher cipher=Cipher.getInstance(keyFactory.getAlgorithm());  
        cipher.init(Cipher.ENCRYPT_MODE, pubKey);  
        byte [] result = cipher.doFinal(src.getBytes());
		return result;
	}

	/**
	 * 获取私钥
	 * @param keyPair
	 * @return
	 */
	public static PrivateKey getPrivateKey(KeyPair keyPair) {
		PrivateKey privateKey= keyPair.getPrivate();
		return privateKey;
	}

	/**
	 * 获取公钥 
	 * @param keyPair
	 * @return
	 */
	public static PublicKey getPublicKey(KeyPair keyPair) {
		PublicKey publicKey= keyPair.getPublic();
		return publicKey;
	}

	private static KeyPair getKeyPair() throws NoSuchAlgorithmException,
			InvalidParameterSpecException, InvalidAlgorithmParameterException {
		//加入对BouncyCastle支持  
        Security.addProvider(new BouncyCastleProvider());  
        AlgorithmParameterGenerator apg=AlgorithmParameterGenerator.getInstance("ElGamal");  
        //初始化参数生成器  
        apg.init(256);  
        //生成算法参数  
        AlgorithmParameters params=apg.generateParameters();  
        //构建参数材料  
        DHParameterSpec elParams=(DHParameterSpec)params.getParameterSpec(DHParameterSpec.class);  
        //实例化密钥生成器  
        KeyPairGenerator kpg=KeyPairGenerator.getInstance("ElGamal") ;  
        //初始化密钥对生成器  
        kpg.initialize(elParams,new SecureRandom());  
        KeyPair keyPair=kpg.generateKeyPair();
		return keyPair;
	}
}




猜你喜欢

转载自blog.csdn.net/qq_31301681/article/details/77914293