对称加密算法(JDK和BC实现方式)
DES (是数据加密标准,很多年前常用,已被破解不具备安全性)
3DES(三重DES,又称:Triple DES或DESede)
AES (是目前最常用的方式;因为3DES速度较慢;AES通常用于移动通信系统加密以及基于SSH协议的软件)
PBE (基于口令的加密,未举例)
非对称加密算法(JDK和BC实现方式)
公钥+密钥
DH(密钥交换算法)
RSA(基于因子分解,最常用)
ELGamal (椭圆曲线加密,未举例)
如何安全的传递密钥,是对称加密算法的困扰;但非对称加密算法就很好的解决了这个问题
数字证书
用于验证,而不是用于解密
3DES
JDK和BC 的3DES 是非常相似的
JDK和BC 的DES 也是非常相似的,把DESede改成DES就是DES算法了
import org.apache.commons.codec.binary.Hex;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.junit.jupiter.api.Test;
import javax.crypto.*;
import javax.crypto.spec.DESedeKeySpec;
import java.security.Key;
import java.security.SecureRandom;
import java.security.Security;
public class options2 {
private static String src = "ruhuashop.com";
@Test
public void index() {
jdk3DES();
bc3DES();
}
private static void jdk3DES() {
try {
//生成KEY
KeyGenerator keyGenerator = KeyGenerator.getInstance("DESede");
keyGenerator.init(168);
keyGenerator.init(new SecureRandom());
SecretKey secretKey = keyGenerator.generateKey();
byte[] bytesKey = secretKey.getEncoded();
//KEY转换
DESedeKeySpec desKeySpec = new DESedeKeySpec(bytesKey);
SecretKeyFactory factory = SecretKeyFactory.getInstance("DESede");
Key convertSecretKey = factory.generateSecret(desKeySpec);
//加密
Cipher cipher = Cipher.getInstance("DESede/ECB/PKCS5Padding");
cipher.init(Cipher.ENCRYPT_MODE, convertSecretKey);
byte[] result = cipher.doFinal(src.getBytes());
System.out.println("jdk 3des encrypt : " +Hex.encodeHexString(result));
//解密
cipher.init(Cipher.DECRYPT_MODE, convertSecretKey);
result = cipher.doFinal(result);
System.out.println("jdk 3des decrypt : " +new String(result));
} catch(Exception e){
e.printStackTrace();
}
}
public static void bc3DES() {
try {
Security.addProvider(new BouncyCastleProvider());
//生成KEY
KeyGenerator keyGenerator = KeyGenerator.getInstance("DESede","BC");
keyGenerator.getProvider();
keyGenerator.init(168);
SecretKey secretKey = keyGenerator.generateKey();
byte[] bytesKey = secretKey.getEncoded();
//KEY转换
DESedeKeySpec desKeySpec = new DESedeKeySpec(bytesKey);
SecretKeyFactory factory = SecretKeyFactory.getInstance("DESede");
Key convertSecretKey = factory.generateSecret(desKeySpec);
//加密
Cipher cipher = Cipher.getInstance("DESede/ECB/PKCS5Padding");
cipher.init(Cipher.ENCRYPT_MODE, convertSecretKey);
byte[] result = cipher.doFinal(src.getBytes());
System.out.println("jdk 3des encrypt : " + Hex.encodeHexString(result));
//解密
cipher.init(Cipher.DECRYPT_MODE, convertSecretKey);
result = cipher.doFinal(result);
System.out.println("jdk 3des decrypt : " +new String(result));
} catch (Exception e) {
e.printStackTrace();
}
}
}
AES
BC方式的AES和JDK很相似,所以以上只举例一种
public static void jdkAES() {
try {
//生成KEY
KeyGenerator keyGenerator = KeyGenerator.getInstance("AES");keyGenerator.init(128);
SecretKey secretKey = keyGenerator.generateKey();
byte[] keyBytes = secretKey.getEncoded();
//key转换
Key key = new SecretKeySpec(keyBytes, "AES");
//加密
Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");cipher.init(Cipher.ENCRYPT_MODE, key);
byte[] result = cipher.doFinal(src.getBytes());
System.out.println("jdk aes encrypt : " + Base64.encodeBase64String(result));
//解密
cipher.init(Cipher.DECRYPT_MODE, key);result = cipher.doFinal(result);
System.out.println("jdk aes desrypt : " + new String(result));
}catch (Exception e){
e.printStackTrace();
}
}
DH
public static void jdkDH() {
try {
// 初始化发送方密钥
KeyPairGenerator senderKeyPairGenerator = KeyPairGenerator.getInstance("DH");
senderKeyPairGenerator.initialize(512);
KeyPair senderKeyPair = senderKeyPairGenerator.generateKeyPair();
byte[] senderPublicKey = senderKeyPair.getPublic().getEncoded();
// 初始化接收方的密钥
KeyFactory instance = KeyFactory.getInstance("DH");
X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(senderPublicKey);
PublicKey sendPublicKeyTemp = instance.generatePublic(x509EncodedKeySpec);
DHParameterSpec dhParameterSpec = ((DHPublicKey) sendPublicKeyTemp).getParams();
KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("DH");
keyPairGenerator.initialize(dhParameterSpec);
// 接收方生成密钥
KeyPair generateKeyPair = keyPairGenerator.generateKeyPair();
byte[] receiverPublicKey = generateKeyPair.getPublic().getEncoded();
PrivateKey receiverPrivateKey = generateKeyPair.getPrivate();
// 接收方密钥构建
KeyAgreement receiverKeyAgreement = KeyAgreement.getInstance("DH");
receiverKeyAgreement.init(receiverPrivateKey);
receiverKeyAgreement.doPhase(senderKeyPair.getPublic(), true);
// 使用我的密钥和你的公钥生成密钥
SecretKey receiverDesKey = receiverKeyAgreement.generateSecret("DES");
System.out.println("receiverDesKey:"+receiverDesKey);
// 发送方密钥构建
KeyFactory keyFactory = KeyFactory.getInstance("DH");
X509EncodedKeySpec x509EncodedKeySpec2 = new X509EncodedKeySpec(receiverPublicKey);
PublicKey receiverPublicKeyTemp = keyFactory.generatePublic(x509EncodedKeySpec2);
// 发送方拿到接收方返回的公钥做本地密钥
KeyAgreement senderKeyAgreement = KeyAgreement.getInstance("DH");
senderKeyAgreement.init(senderKeyPair.getPrivate());
senderKeyAgreement.doPhase(receiverPublicKeyTemp, true);
// 使用你的密钥我的公钥进行构建
SecretKey senderDesKey = senderKeyAgreement.generateSecret("DES");
System.out.println("senderDesKey:" + senderDesKey);
// 判断双方的本地密钥是否相同
if (Objects.equals(receiverDesKey, senderDesKey)) {
System.out.println("双方密钥相同");
}
// 加密
Cipher cipher = Cipher.getInstance("DES");
cipher.init(Cipher.ENCRYPT_MODE, senderDesKey);
byte[] result = cipher.doFinal(src.getBytes());
System.out.println("加密结果为 : " + Hex.encodeHexString(result));
// 解密
cipher.init(Cipher.DECRYPT_MODE, senderDesKey);
result = cipher.doFinal(result);
System.out.println("解密结果为 : " + new String(result));
}catch (Exception e){
e.printStackTrace();
}
}
由于JDK8 update 161之后,DH的密钥长度至少为512位,但AES算法密钥不能达到这样的长度,长度不一致所以导致报错。
解决的方法:将 -Djdk.crypto.KeyAgreement.legacyKDF=true 写入JVM系统变量中
RSA算法
- 唯一广泛接受并实现
- 数据加密&数字签名
- 公钥加密、私钥解密
- 私钥加密、公钥解密
public static void jdkRSA() {
try {
// 构建密钥对儿
KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
keyPairGenerator.initialize(512);
KeyPair keyPair = keyPairGenerator.generateKeyPair();
RSAPublicKey rsaPublicKey = (RSAPublicKey) keyPair.getPublic();
RSAPrivateKey rsaPrivateKey = (RSAPrivateKey) keyPair.getPrivate();
System.out.println("Public Key : " + org.apache.commons.codec.binary.Base64.encodeBase64String(rsaPublicKey.getEncoded()));
System.out.println("Private Key : " + org.apache.commons.codec.binary.Base64.encodeBase64String(rsaPrivateKey.getEncoded()));
// 2.私钥加密,公钥解密---加密
PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(rsaPrivateKey.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(src.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 = Cipher.getInstance("RSA");
cipher.init(Cipher.ENCRYPT_MODE, publicKey);
result = cipher.doFinal(src.getBytes());
System.out.println("公钥加密,私钥解密------加密 : " + Base64.encodeBase64String(result));
// 5.公钥加密,私钥解密---解密
pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(rsaPrivateKey.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 static void jdkRSASign() {
try {
//1.初始化密钥
KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
keyPairGenerator.initialize(512);
KeyPair keyPair = keyPairGenerator.generateKeyPair();
RSAPublicKey rsaPublicKey = (RSAPublicKey)keyPair.getPublic(); //公钥验证
RSAPrivateKey rsaPrivateKey = (RSAPrivateKey)keyPair.getPrivate(); //私钥签名
//2.执行签名
PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(rsaPrivateKey.getEncoded());
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
PrivateKey privateKey = keyFactory.generatePrivate(pkcs8EncodedKeySpec);
Signature signature = Signature.getInstance("MD5withRSA");
signature.initSign(privateKey);
signature.update(src.getBytes());
byte[] result = signature.sign();
System.out.println("jdk rsa sign : " + Hex.encodeHexString(result));
//3.验证签名
X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(rsaPublicKey.getEncoded());
keyFactory = KeyFactory.getInstance("RSA");
PublicKey publicKey = keyFactory.generatePublic(x509EncodedKeySpec);
signature = Signature.getInstance("MD5withRSA");
signature.initVerify(publicKey);
signature.update(src.getBytes());
boolean bool = signature.verify(result);
System.out.println("jdk rsa verify : " + bool);
} catch (Exception e) {
e.printStackTrace();
}
}
网友评论