非对称加密算法-DH,RSA,ElGamal

代码参考URL:http://www.imooc.com/learn/288

1.非对称加密算法--DH

流程说明参考的文章:http://blog.csdn.net/sunny_sailor/article/details/7445649

DH的流程:

1.甲方构建密钥对儿,将公钥公布给乙方,将私钥保留;双方约定数据加密算法;乙方通过甲方公钥构建密钥对儿,将公钥公布给甲方,将私钥保留。 
2.甲方使用私钥、乙方公钥、约定数据加密算法构建本地密钥,然后通过本地密钥加密数据,发送给乙方加密后的数据;乙方使用私钥、甲方公钥、约定数据加密算法构建本地密钥,然后通过本地密钥对数据解密。 
3.乙方使用私钥、甲方公钥、约定数据加密算法构建本地密钥,然后通过本地密钥加密数据,发送给甲方加密后的数据;甲方使用私钥、乙方公钥、约定数据加密算法构建本地密钥,然后通过本地密钥对数据解密。


1.使用jdk,bc来实现对应代码:

package com.samlai.security.asyEncry;

import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.Security;
import java.security.spec.X509EncodedKeySpec;
import java.util.Objects;

import javax.crypto.Cipher;
import javax.crypto.KeyAgreement;
import javax.crypto.SecretKey;
import javax.crypto.interfaces.DHPublicKey;
import javax.crypto.spec.DHParameterSpec;

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


public class DHStudy {
	/**
	 * 非对称加密算法 -DH(密钥交换)
	 *  对称加密带来的困扰
	 *  构建本地密钥
	 *  对称
	 */
	private static String STR = "one type of security:DH";
	
	public static void main(String[] args) {
		jdkDH();
		bcDH();
	}
	
	
	//jdk实现DH
	public static void jdkDH(){
		try {
			//初始化发送方密钥
			KeyPairGenerator senderKeyPairGenerator=KeyPairGenerator.getInstance("DH");
			senderKeyPairGenerator.initialize(512);
			KeyPair senderKeyPair=senderKeyPairGenerator.generateKeyPair();
			//发送方公钥,发送给收方(网络,文件)
			byte[] senderPublicKeyEnc=senderKeyPair.getPublic().getEncoded();
			
			//初始化接收方密钥
			KeyFactory receiverKeyFactory=KeyFactory.getInstance("DH");
			X509EncodedKeySpec x509EncodedKeySpec=new X509EncodedKeySpec(senderPublicKeyEnc);
			PublicKey receiverPublicKey=receiverKeyFactory.generatePublic(x509EncodedKeySpec);
			DHParameterSpec dhParameterSpec=((DHPublicKey)receiverPublicKey).getParams();
			KeyPairGenerator receiverKeyPairGenerator=KeyPairGenerator.getInstance("DH");
			receiverKeyPairGenerator.initialize(dhParameterSpec);
			KeyPair receiverKeyPair=receiverKeyPairGenerator.generateKeyPair();
			PrivateKey reveiverPrivateKey=receiverKeyPair.getPrivate();
			byte[] receiverPublicKeyEnc=receiverKeyPair.getPublic().getEncoded();
			
			//密钥构建
			KeyAgreement receiverKeyAgreement=KeyAgreement.getInstance("DH");
			receiverKeyAgreement.init(reveiverPrivateKey);
			receiverKeyAgreement.doPhase(receiverPublicKey, true);
			SecretKey receiverDesKey=receiverKeyAgreement.generateSecret("DES");
			
			KeyFactory senderKeyFactory=KeyFactory.getInstance("DH");
			x509EncodedKeySpec=new X509EncodedKeySpec(receiverPublicKeyEnc);
			PublicKey senderPublicKey=senderKeyFactory.generatePublic(x509EncodedKeySpec);
			KeyAgreement senderKeyAgreement=KeyAgreement.getInstance("DH");
			senderKeyAgreement.init(senderKeyPair.getPrivate());
			senderKeyAgreement.doPhase(senderPublicKey, true);
			SecretKey senderDesKey=senderKeyAgreement.generateSecret("DES");
			if(Objects.equals(receiverDesKey, senderDesKey)){
				System.out.println("双方密钥相同");
			}
			
			//加密
			Cipher cipher=Cipher.getInstance("DES");
			cipher.init(Cipher.ENCRYPT_MODE, senderDesKey);
			byte[] result=cipher.doFinal(STR.getBytes());
			System.out.println("jdk DH encode: "+Base64.encodeBase64String(result));
			
			
			//解密
			cipher.init(Cipher.DECRYPT_MODE, receiverDesKey);
			result=cipher.doFinal(result);
			System.out.println("jdk DH decode: "+new String(result));
			
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	
	//bc实现DH算法
	public static void bcDH(){
		try {
			Security.addProvider(new BouncyCastleProvider());
			//初始化发送方密钥
			KeyPairGenerator senderKeyPairGenerator=KeyPairGenerator.getInstance("DH","BC");
			senderKeyPairGenerator.getProvider();
			senderKeyPairGenerator.initialize(512);
			KeyPair senderKeyPair=senderKeyPairGenerator.generateKeyPair();
			//发送方公钥,发送给收方(网络,文件)
			byte[] senderPublicKeyEnc=senderKeyPair.getPublic().getEncoded();
			
			//初始化接收方密钥
			KeyFactory receiverKeyFactory=KeyFactory.getInstance("DH");
			X509EncodedKeySpec x509EncodedKeySpec=new X509EncodedKeySpec(senderPublicKeyEnc);
			PublicKey receiverPublicKey=receiverKeyFactory.generatePublic(x509EncodedKeySpec);
			DHParameterSpec dhParameterSpec=((DHPublicKey)receiverPublicKey).getParams();
			KeyPairGenerator receiverKeyPairGenerator=KeyPairGenerator.getInstance("DH","BC");
			receiverKeyPairGenerator.getProvider();
			receiverKeyPairGenerator.initialize(dhParameterSpec);
			KeyPair receiverKeyPair=receiverKeyPairGenerator.generateKeyPair();
			PrivateKey reveiverPrivateKey=receiverKeyPair.getPrivate();
			byte[] receiverPublicKeyEnc=receiverKeyPair.getPublic().getEncoded();
			
			//密钥构建
			KeyAgreement receiverKeyAgreement=KeyAgreement.getInstance("DH");
			receiverKeyAgreement.init(reveiverPrivateKey);
			receiverKeyAgreement.doPhase(receiverPublicKey, true);
			SecretKey receiverDesKey=receiverKeyAgreement.generateSecret("DES");
			
			KeyFactory senderKeyFactory=KeyFactory.getInstance("DH");
			x509EncodedKeySpec=new X509EncodedKeySpec(receiverPublicKeyEnc);
			PublicKey senderPublicKey=senderKeyFactory.generatePublic(x509EncodedKeySpec);
			KeyAgreement senderKeyAgreement=KeyAgreement.getInstance("DH");
			senderKeyAgreement.init(senderKeyPair.getPrivate());
			senderKeyAgreement.doPhase(senderPublicKey, true);
			SecretKey senderDesKey=senderKeyAgreement.generateSecret("DES");
			if(Objects.equals(receiverDesKey, senderDesKey)){
				System.out.println("双方密钥相同");
			}
			
			//加密
			Cipher cipher=Cipher.getInstance("DES");
			cipher.init(Cipher.ENCRYPT_MODE, senderDesKey);
			byte[] result=cipher.doFinal(STR.getBytes());
			System.out.println("bc DH encode: "+Base64.encodeBase64String(result));
			
			
			//解密
			cipher.init(Cipher.DECRYPT_MODE, receiverDesKey);
			result=cipher.doFinal(result);
			System.out.println("bc DH decode: "+new String(result));
			
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}

运行的结果:

双方密钥相同
jdk DH encode: XbmK/tkwVlYao3lhJvLWqceJ8QiYkODa
jdk DH decode: one type of security:DH
双方密钥相同
bc DH encode: Ehu42tOe7AmwMLOAAf2S4/1pwnX+91Iy
bc DH decode: one type of security:DH

2.jdk实现RSA算法:

package com.samlai.security.asyEncry;

import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;

import javax.crypto.Cipher;

import org.apache.commons.codec.binary.Base64;

public class RSAStudy {
	/**
	 * 非对称加密算法 --RSA
	 * 基于大数因子分解
	 * 	唯一广泛接受并实现
	 * 	数据加密&数字签名
	 * 	公钥加密 私钥解密
	 * 	私钥加密 公钥解密
	 */
	private static String STR = "one type of security:RSA";
	
	public static void main(String[] args) {
		jdkRSA();
	}
	
	//jdk实现RSA加密
	public static void jdkRSA(){
		try {
			//1.初始化密钥
			KeyPairGenerator keyPairGenerator=KeyPairGenerator.getInstance("RSA");
			keyPairGenerator.initialize(512);
			KeyPair keyPair=keyPairGenerator.generateKeyPair();
			RSAPublicKey rsaPublicKey=(RSAPublicKey)keyPair.getPublic();
			RSAPrivateKey rsaPrivate=(RSAPrivateKey)keyPair.getPrivate();
			//打印出来的公钥是比私钥短较多的,公钥公开,较短较容易保存
			System.out.println("public Key: "+Base64.encodeBase64String(rsaPublicKey.getEncoded()));
			System.out.println("private Key: "+Base64.encodeBase64String(rsaPrivate.getEncoded()));
			
			
			//2.私钥加密,公钥解密---加密
			PKCS8EncodedKeySpec pkcs8EncodedKeySpec=new PKCS8EncodedKeySpec(rsaPrivate.getEncoded());
			KeyFactory keyFactory=KeyFactory.getInstance("RSA");
			PrivateKey privateKey=keyFactory.generatePrivate(pkcs8EncodedKeySpec);
			Cipher cipher=Cipher.getInstance("RSA");
			cipher.init(Cipher.ENCRYPT_MODE, privateKey);
			byte[] result=cipher.doFinal(STR.getBytes());
			System.out.println("私钥加密,公钥解密---加密: "+Base64.encodeBase64String(result));
			
			//3.私钥加密,公钥解密---解密
			X509EncodedKeySpec x509EncodedKeySpec=new X509EncodedKeySpec(rsaPublicKey.getEncoded());
			keyFactory=KeyFactory.getInstance("RSA");
			PublicKey publicKey=keyFactory.generatePublic(x509EncodedKeySpec);
			cipher=Cipher.getInstance("RSA");
			cipher.init(Cipher.DECRYPT_MODE, publicKey);
			result=cipher.doFinal(result);
			System.out.println("私钥加密,公钥解密---解密: "+new String(result));
			
			
			//4.公钥加密,私钥解密 --- 加密[与上面非常的相近的]
			x509EncodedKeySpec=new X509EncodedKeySpec(rsaPublicKey.getEncoded());
			keyFactory=KeyFactory.getInstance("RSA");
			publicKey=keyFactory.generatePublic(x509EncodedKeySpec);
			cipher.init(Cipher.ENCRYPT_MODE, publicKey);
			result=cipher.doFinal(result);
			System.out.println("公钥加密,私钥解密 --- 加密: "+Base64.encodeBase64String(result));
			
			//5.公钥加密,私钥解密 --- 解密
			pkcs8EncodedKeySpec=new PKCS8EncodedKeySpec(rsaPrivate.getEncoded());
			keyFactory=KeyFactory.getInstance("RSA");
			privateKey=keyFactory.generatePrivate(pkcs8EncodedKeySpec);
			cipher=Cipher.getInstance("RSA");
			cipher.init(Cipher.DECRYPT_MODE, privateKey);
			result=cipher.doFinal(result);
			System.out.println("公钥加密,私钥解密 --- 解密: "+new String(result));
		} catch (Exception e) {
			e.printStackTrace();
		}
		
	}
}

运行的结果:

public Key: MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAM0TUZSywLpr8e3UGhCM84/LQT+LS64OUXTFn9O5Kt/dOg+eiYdBKSON1cfVJWAsEAuIKYwFwl2z1PfxBkZ01r0CAwEAAQ==
private Key: MIIBVQIBADANBgkqhkiG9w0BAQEFAASCAT8wggE7AgEAAkEAzRNRlLLAumvx7dQaEIzzj8tBP4tLrg5RdMWf07kq3906D56Jh0EpI43Vx9UlYCwQC4gpjAXCXbPU9/EGRnTWvQIDAQABAkBolsG0pLXGXec09EeWyUwuueq9Db27N3Izq9anlHhZUv/PLIg83/Ucxl5NTDFfxPiBHqtYWUsAprOvxUqORzABAiEA/DK5wwaH7kOf+EE0ytMzlb2rwYM7Semx6OhrM23eVUECIQDQKr0i1LpRU2caCS5F3wc+FkrZF1ajZBA6EsNDUQm2fQIgKyJd5T5Tt2u3i5VTezE+TGkhXDqexFiFBkniM+yhr0ECIQCxm4V77lx5ftt8z1B3tO6M/qAl0U/OYFWn9tI64S2UUQIhAOh4v+zANLyfdFKNeau/zIeRLGYXzDd8lUg2KQuHPzB4
私钥加密,公钥解密---加密: Oy+z3Ncym67f7tYYoulFDfjTn3tQK3YQ+Dx/UhBljsSC2WTf2ZnlT6+EK+rqSyqkOK93w00tNoeGrYdlWMAlSw==
私钥加密,公钥解密---解密: one type of security:RSA
公钥加密,私钥解密 --- 加密: uLndrx+xnmR6en3f4gfEnY9u9vrf4UnDIUcM5+zXc4ykSBk628x0vKT+UuRYBY30Pyh60aoBz0FLbuimGBKQNw==
公钥加密,私钥解密 --- 解密: one type of security:RSA

RSA运用的流程如下:



3.ElGamal算法实现

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

条件:因为ElGamal加密的长度为8的倍数,160-16384位,由于from us所以对加密长度有进行限制的,(大于128位时)所以本身我们本地的jdk是对这些文件是有限制,故需要下载额外的jar文件:US_export_policy.jar,local_policy.jar 替换的本地的java的jdk目录下的jre的security下2jar包就可以正确执行ElGamal代码了

参考url:http://stackoverflow.com/questions/6481627/java-security-illegal-key-size-or-default-parameters

package com.samlai.security.asyEncry;


import java.security.AlgorithmParameterGenerator;
import java.security.AlgorithmParameters;
import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.SecureRandom;
import java.security.Security;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;


import javax.crypto.Cipher;
import javax.crypto.spec.DHParameterSpec;

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

public class ElGamalStudy {
	
	/**
	 * 没有jdk实现,bc提供
	 * 公钥加密算法
	 * 密钥长度:8的倍数 160>
	 * 
	 */
	private static String STR = "one type of security:ElGamal";
	public static void main(String[] args) {
		bcElGamal();
	}
	//jdk实现RSA加密
	public static void bcElGamal(){
		try {
			Security.addProvider(new BouncyCastleProvider());
			//初始化密钥
			AlgorithmParameterGenerator algorithmParameterGenerator=AlgorithmParameterGenerator.getInstance("ElGamal");
			algorithmParameterGenerator.init(256);
			AlgorithmParameters algorithmParameters=algorithmParameterGenerator.generateParameters();
			DHParameterSpec dhParameterSpec=(DHParameterSpec)algorithmParameters.getParameterSpec(DHParameterSpec.class);
			KeyPairGenerator keyPairGenerator=KeyPairGenerator.getInstance("ElGamal");
			keyPairGenerator.initialize(dhParameterSpec,new SecureRandom());
			KeyPair keyPair=keyPairGenerator.generateKeyPair();
			//构建对应的密钥对
			PublicKey elGamalPublicKey=keyPair.getPublic();
			PrivateKey elGamalPrivateKey=keyPair.getPrivate();
			
			System.out.println("Public Key: "+Base64.encodeBase64String(elGamalPublicKey.getEncoded()));
			System.out.println("Private Key: "+Base64.encodeBase64String(elGamalPrivateKey.getEncoded()));;
			
			
			//步骤是:
			/**
			 * 1.在接收者上进行构建密钥对就是公钥跟私钥
			 * 2.由接收者进行发布公钥,再由发布者进行公钥进行加密数据,再进行传输加密数据
			 * 3.接收者进行接收数据,由私钥进行解密
			 */
			
			//公钥加密,私钥解密 ----- 加密
//			X509EncodedKeySpec x509EncodedKeySpec=new X509EncodedKeySpec(elGamalPublicKey.getEncoded());
//			KeyFactory keyFactory=KeyFactory.getInstance("ElGamal");
//			PublicKey publicKey=keyFactory.generatePublic(x509EncodedKeySpec);
			Cipher cipher=Cipher.getInstance("ElGamal");
			cipher.init(Cipher.ENCRYPT_MODE, elGamalPublicKey);
			byte[] result=cipher.doFinal(STR.getBytes());
			System.out.println("ElGamals算法,公钥加密,私钥解密-----加密: "+Base64.encodeBase64String(result));
			
//			PKCS8EncodedKeySpec pkcs8EncodedKeySpec=new PKCS8EncodedKeySpec(elGamalPrivateKey.getEncoded());
//			keyFactory=KeyFactory.getInstance("ElGamal");
//			PrivateKey privateKey=keyFactory.generatePrivate(pkcs8EncodedKeySpec);
			cipher=Cipher.getInstance("ElGamal");
			cipher.init(Cipher.DECRYPT_MODE, elGamalPrivateKey);
			result=cipher.doFinal(result);
			System.out.println("ElGamals算法,公钥加密,私钥解密-----解密: "+new String(result));
			
			
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}

运行结果:

Public Key: MHcwUAYGKw4HAgEBMEYCIQDLb7VPLae2lzgRPOjD8dXsxxsuDaZVEdXjknwg4b2g/wIhAIdAvANdNVDdJ7JZoPZBpzWzKe9PA94xpPe59+fARTE4AyMAAiAG6zKE1VmQofKM6+oIYAYE4+sze9UT5eYPOx4rdAlBbQ==
Private Key: MHkCAQAwUAYGKw4HAgEBMEYCIQDLb7VPLae2lzgRPOjD8dXsxxsuDaZVEdXjknwg4b2g/wIhAIdAvANdNVDdJ7JZoPZBpzWzKe9PA94xpPe59+fARTE4BCICIAUlzfqi879n8oJfQcIDUniu4yaJ1JRA5G0RIj58XuCE
ElGamals算法,公钥加密,私钥解密-----加密: ToLmNsaIM422cRKXOoJbyPy2ta2lzhVR1bmlEGv/+VuAkKeVpqj5XKjE1wMWVQCHP5t6UTBPIcPAdNQbydhxXQ==
ElGamals算法,公钥加密,私钥解密-----解密: one type of security:ElGamal





  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值