欢迎大家来我的博客:http://www.qnloft.com 交流学习还可以观看视频教程
切入正题,今天需要和某国有(大型)银行系统对接,对方使用RSA
对敏感数据进行加密返回,不得已,我要研究一下RSA
加密算法了,本着探索(懒)精神,由于Google还没回归,所以先百度瞅瞅。一搜一大片文章,使用排除法,先排除互相抄袭的,年代久远的等等…最后找到这么两篇
不得不夸一下我大优快云没少给百度送钱吧~!O(∩_∩)O哈哈~
将两篇文章代码取长补短,整合了一下,发现还是不行。不禁仰天长叹,好坑啊……….
填坑之旅
RSA算法分为生成私钥和公钥,可以选择:
- 私匙加密,必须公钥解密。
- 公钥加密,必须私匙解密。
生成私钥和公钥代码如下:
KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance("RSA");
keyPairGen.initialize(1024);
KeyPair keyPair = keyPairGen.generateKeyPair();
// 私匙
RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();
// 公匙
RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();
现在我使用生成的公匙加密,私匙解密,代码如下:
/**
* 公匙加密
* @param privateKey
* @param obj
* @return
*/
protected byte[] encrypt(RSAPublicKey privateKey, byte[] obj) {
if (privateKey != null) {
try {
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.ENCRYPT_MODE, privateKey);
return cipher.doFinal(obj);
} catch (Exception e) {
e.printStackTrace();
}
}
return null;
}
/**
* 私匙解密
* @param privateKey
* @param obj
* @return
*/
protected byte[] decrypt(RSAPrivateKey privateKey, byte[] obj) {
if (privateKey != null) {
try {
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.DECRYPT_MODE, privateKey);
return cipher.doFinal(obj);
} catch (Exception e) {
e.printStackTrace();
}
}
return null;
}
加密后的密文,需要再经过base64
一下才传播。
现在贴出完整的代码:
import javax.crypto.Cipher;
import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.PrivateKey;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.util.Base64;
/**
* @author : R&M www.qnloft.com/blog
* 2018/8/14 11:08
*
*/
public class RSATest {
public static void main(String[] args) {
try {
RSATest encrypt = new RSATest();
KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance("RSA");
keyPairGen.initialize(1024);
KeyPair keyPair = keyPairGen.generateKeyPair();
// RSAPrivateKey privateKey = (RSAPrivateKey) getPrivateKey(ConstantForEnterprise.PSBC_SECRET_KEY);
// 私匙
RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();
// 公匙
RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();
String str = "123456789012345678!测试";
System.out.println("需要加密的内容是: " + str);
byte[] e = encrypt.encrypt(publicKey, str.getBytes());
String publicValue = encodeBase64(e);
System.out.println("密文是:" + publicValue);
byte[] d = encrypt.decrypt(privateKey, decodeBase64(publicValue));
System.out.println("解密后的结果是: " + new String(d));
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 公匙加密
* @param privateKey
* @param obj
* @return
*/
protected byte[] encrypt(RSAPublicKey privateKey, byte[] obj) {
if (privateKey != null) {
try {
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.ENCRYPT_MODE, privateKey);
return cipher.doFinal(obj);
} catch (Exception e) {
e.printStackTrace();
}
}
return null;
}
/**
* 私匙解密
* @param privateKey
* @param obj
* @return
*/
protected byte[] decrypt(RSAPrivateKey privateKey, byte[] obj) {
if (privateKey != null) {
try {
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.DECRYPT_MODE, privateKey);
return cipher.doFinal(obj);
} catch (Exception e) {
e.printStackTrace();
}
}
return null;
}
/**
* String类型的密匙转私匙
* @param privateKey
* @return
* @throws Exception
*/
private static PrivateKey getPrivateKey(String privateKey) throws Exception {
byte[] keyBytes = Base64.getDecoder().decode(privateKey.getBytes());
PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(keyBytes);
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
return keyFactory.generatePrivate(keySpec);
}
private static String encodeBase64(byte[] binaryData) {
return Base64.getEncoder().encodeToString(binaryData);
}
private static byte[] decodeBase64(String encoded){
return Base64.getDecoder().decode(encoded);
}
}
到这里就结束了,PrivateKey
和PublicKey
代表了密匙和公匙的对象,适当的修改就可以变成密匙加密,公匙解密了。
Base64.getDecoder().decode(encoded)
这里一定要使用java8的类,要不maven打包出错,我会再写一篇文章讲这个事情。