非对称加密算法——RSA
RSA是唯一被广泛接受并实现的通用算法。
RSA有两种模式公钥加密私钥解密和私钥加密公钥解密两种模式,其序列图如下:
在RSA算法中公钥的长度远远小于私钥的长度。以下是其java实现:
============================================================================RSA加解密工具类:
import java.security.Key;
import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.HashMap;
import java.util.Map;
import javax.crypto.Cipher;
public class SecurityRSA {
//公钥
private static final String PUBLIC_KEY = "RSAPublicKey";
//私钥
private static final String PRIVATE_KEY = "RSAPrivateKey";
/** 初始化密钥对
* @return Map 密钥对Map
* @throws Exception
*/
public static Map<String, Object> initKey() {
try {
//实例化密钥对生成器
KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
// 初始化密钥对生成器,密钥大小为96-1024位
keyPairGenerator.initialize(1024, new SecureRandom());
//生成密钥对
KeyPair keyPair = keyPairGenerator.generateKeyPair();
//公钥
RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();
//私钥
RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();
//将密钥对存储在Map中
Map<String, Object> keyMap = new HashMap<String, Object>(2);
keyMap.put(PUBLIC_KEY, publicKey);
keyMap.put(PRIVATE_KEY, privateKey);
return keyMap;
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
return null;
}
/** 加密【公钥加密,私钥解密】
* @param data 待加密数据
* @param key 公钥
* @return byte[] 加密数据
* @throws Exception
*/
public static byte[] encrypt(byte[] data, byte[] key) {
try {
RSAPublicKey pubKey = (RSAPublicKey) KeyFactory.getInstance("RSA")
.generatePublic(new X509EncodedKeySpec(key));
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.ENCRYPT_MODE, pubKey);
byte[] result = cipher.doFinal(data);
return result;
} catch (Exception ex) {
ex.printStackTrace();
}
return null;
}
/** 解密【公钥加密,私钥解密】
* @param data 待解密数据
* @param key 私钥
* @return byte[] 解密数据
* @throws Exception
*/
public static byte[] decrypt(byte[] data, byte[] key) {
try {
RSAPrivateKey priKey = (RSAPrivateKey) KeyFactory.getInstance("RSA")
.generatePrivate(new PKCS8EncodedKeySpec(key));
//实例化
Cipher cipher = Cipher.getInstance("RSA");
//使用密钥初始化,设置为解密模式
cipher.init(Cipher.DECRYPT_MODE, priKey);
//执行操作
byte[] result = cipher.doFinal(data);
return result;
} catch (Exception ex) {
ex.printStackTrace();
}
return null;
}
/** 取得私钥
* @param keyMap 密钥Map
* @return byte[] 私钥
* @throws Exception
*/
public static byte[] getPrivateKey(Map<String, Object> keyMap) {
Key key = (Key) keyMap.get(PRIVATE_KEY);
return key.getEncoded();
}
/** 取得公钥
* @param keyMap 密钥Map
* @return byte[] 公钥
* @throws Exception
*/
public static byte[] getPublicKey(Map<String, Object> keyMap) {
Key key = (Key) keyMap.get(PUBLIC_KEY);
return key.getEncoded();
}
}
============================================================================RSA加解密工具测试类:
@Test
public void test_RSA() {
//公钥
byte[] publicKey;
//私钥
byte[] privateKey;
//初始化密钥
//生成甲方密钥对
Map<String, Object> keyMap = SecurityRSA.initKey();
publicKey = SecurityRSA.getPublicKey(keyMap);
privateKey = SecurityRSA.getPrivateKey(keyMap);
System.out.println("RSA公钥:\n" + org.apache.commons.codec.binary.Base64.encodeBase64String(publicKey));
System.out.println("RSA私钥:\n" + org.apache.commons.codec.binary.Base64.encodeBase64String(privateKey));
System.out.println();
System.out.println("===甲方向乙方发送加密数据===");
String msgA2B = "求知若饥,虚心若愚。";
System.out.println("原文:\n" + msgA2B);
System.out.println("---甲方使用公钥对数据进行加密---");
//使用公钥对数据加密
byte[] encodeMsgA2B = SecurityRSA.encrypt(msgA2B.getBytes(), publicKey);
System.out.println("RSA加密:\n" + org.apache.commons.codec.binary.Base64.encodeBase64String(encodeMsgA2B));
System.out.println("---乙方使用私钥对数据库进行解密---");
//使用私钥对数据进行解密
byte[] msgB2A = SecurityRSA.decrypt(encodeMsgA2B, privateKey);
String output1 = new String(msgB2A);
System.out.println("RSA解密:\n" + output1);
}