代码参考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