简单说明
非对称加密算法中引入了公钥和私钥的概念,他们一一对应,使用公钥加密只能使用对应私钥解密,反之亦然,非对称即是如此。
RSA是一种典型非对称加密算法,它是由三位数学家(Rivest、Shamir、Adleman)设计出来的。
应用场景
- 签名验证
私钥用于加密签名,公钥用于验签,签名和加密作用不同,签名并不是为了保密,而是为了保证数据是由特定的某个人提供,而不是被其它人伪造,所以私钥的私有性就适合用在签名用途上。 - 加密
公钥用于加密,私钥用于解密,因为公钥是公开的,很多人可以持有公钥。若用私钥加密,那所有持有公钥的人都可以进行解密,这是不安全的
RSA密钥生成方法
这里我们选择使用openssl工具生成,操作步骤如下:
- 生成密钥
openssl genrsa -out rsa_pri_key.pem 1024
说明: 其中1024是指密钥长度,密钥长度越长被暴力破解难度越大,长度可选 1024 / 2048 / 3072 / 4096 - 将密钥转换为PKCS8格式
openssl pkcs8 -topk8 -inform PEM -in test_pri_key.pem -outform pem -nocrypt -out test_pri_key_pkcs8.pem
说明: PKCS8是一种密钥存储机制,他在PKCS1标准上进行了加固 - 生成公钥
openssl rsa -in test_pri_key.pem -pubout -out test_public_key.pem
JAVA调用
说明:代码中的私钥(privateKeyStr)和公钥内容(publicKeyStr)要去头去尾,即移除-----BEGIN…头尾部分
1.加载密钥,并使用私钥加密数据
private static RSAPrivateKey loadPrivateKeyByStr(String privateKeyStr)
throws NoSuchAlgorithmException, InvalidKeySpecException {
byte[] buffer = Base64.decodeBase64(privateKeyStr);
PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(buffer);
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
return (RSAPrivateKey) keyFactory.generatePrivate(keySpec);
}
private static byte[] encryptByPrivateKey(byte[] bb, PrivateKey key) throws NoSuchAlgorithmException,
NoSuchPaddingException, IllegalBlockSizeException, BadPaddingException, InvalidKeyException {
Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
cipher.init(Cipher.ENCRYPT_MODE, key);
byte[] doFinal = cipher.doFinal(bb);
return doFinal;
}
2.加载公钥,通过公钥解密数据
private static RSAPublicKey loadPublicKeyByStr(String publicKeyStr)
throws NoSuchAlgorithmException, InvalidKeySpecException {
byte[] buffer = Base64.decodeBase64(publicKeyStr);
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
X509EncodedKeySpec keySpec = new X509EncodedKeySpec(buffer);
RSAPublicKey publicKey = (RSAPublicKey) keyFactory.generatePublic(keySpec);
return publicKey;
}
private static byte[] decryptByPublicKey(byte[] b, PublicKey key) throws NoSuchAlgorithmException,
NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException {
Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
cipher.init(Cipher.DECRYPT_MODE, key);
return cipher.doFinal(b);
}
路漫漫其修远兮,吾将上下而求索。