简单概念
RSA是非对称加密,简单的理解是通过生成一对秘钥(公钥和私钥),可以使用公钥加密文档(私钥也可以),然后用私钥解密文档。在这里需要注意的是公钥和私钥其实都可以加密或者解密文档。
案例:
创建一个加密解密工具类,代码如下:
public class RSAEncryptionUtil {
public static void main(String[] args) throws Exception {
RSAKeyPair keyPair = generateKeyPair();
System.out.println("公钥:" + keyPair.getPublicKey());
System.out.println("私钥:" + keyPair.getPrivateKey());
List<ArchiveDispatch> archiveDispatches = new ArrayList<>();
ArchiveDispatch archiveDispatch = new ArchiveDispatch();
archiveDispatch.setAttachMent("dasda");
archiveDispatch.setBMS("das");
archiveDispatches.add(archiveDispatch);
test(keyPair,JSONObject.toJSONString(archiveDispatches));//这里建议最好是json字符串,后边加密之后也方便获取到对象内容
}
/**
* 公钥加密私钥解密
*/
private static void test(RSAKeyPair keyPair, String source) {
String text1 = null;
try {
text1 = encryptByPublicKey(keyPair.getPublicKey, source);
String text2 = decryptByPrivateKey(keyPair.getPrivateKey, text1);
System.out.println("加密前:" + source);
System.out.println("加密后:" + text1);
System.out.println("解密后:" + text2);
List<ArchiveDispatch> result = JSONObject.parseObject(text2, new TypeReference<ArrayList<ArchiveDispatch>>(){});
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 私钥解密
*
* @param privateKeyText 私钥
* @param text 解密的文本
* @return
* @throws Exception
*/
public static String decryptByPrivateKey(String privateKeyText, String text) throws Exception {
ByteArrayOutputStream out = new ByteArrayOutputStream();
//使用PKCS#8标准作为密钥规范管理的编码格式,该类的命名由此得来。
PKCS8EncodedKeySpec pkcs8EncodedKeySpec5 = new PKCS8EncodedKeySpec(Base64.decodeBase64(privateKeyText.getBytes("UTF-8")));
KeyFactory keyFactory = KeyFactory.getInstance("RSA");//秘钥工厂,指定RSA算法
PrivateKey privateKey = keyFactory.generatePrivate(pkcs8EncodedKeySpec5);//根据PKCS#8标准生成私钥对象
Cipher cipher = Cipher.getInstance("RSA");//Cipher是解密的对象
cipher.init(Cipher.DECRYPT_MODE, privateKey);//初始化指定私钥
//开始解密,这里采用分段解密,如果内容过长的话需要。
String outStr = null;
byte[] inputArray = Base64.decodeBase64(text.getBytes("UTF-8"));
int inputLength = inputArray.length;
System.out.println("加密字节数:" + inputLength);
// 最大加密字节数,超出最大字节数需要分组加密
int MAX_ENCRYPT_BLOCK = 128;
// 标识
int offSet = 0;
byte[] cache = {};
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(baos);
while (inputLength - offSet > 0) {
if (inputLength - offSet > MAX_ENCRYPT_BLOCK) {
cache = cipher.doFinal(inputArray, offSet, MAX_ENCRYPT_BLOCK);//开始解密
offSet += MAX_ENCRYPT_BLOCK;
} else {
cache = cipher.doFinal(inputArray, offSet, inputLength - offSet);
offSet = inputLength;
}
out.write(cache, 0, cache.length);
}
outStr = new String(out.toByteArray());
return outStr;
}
/**
* 公钥加密
*
* @param publicKeyText 公钥
* @param text
* @return
*/
public static String encryptByPublicKey(String publicKeyText, String text) throws Exception {
ByteArrayOutputStream out = new ByteArrayOutputStream();
//使用 X.509 标准作为密钥规范管理的编码格式,
X509EncodedKeySpec x509EncodedKeySpec2 = new X509EncodedKeySpec(Base64.decodeBase64(publicKeyText));
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
PublicKey publicKey = keyFactory.generatePublic(x509EncodedKeySpec2);
Cipher cipher = Cipher.getInstance("RSA");//解密对象
cipher.init(Cipher.ENCRYPT_MODE, publicKey);//初始化
int textLength = text.getBytes("UTF-8").length;//总加密长度
int offset = 0;
int i = 0;
int subSize = 117;//分段加密长度,这个是最大的长度
byte[] cache ;
while (textLength - offset > 0){
if (textLength - offset > subSize){
cache = cipher.doFinal(text.getBytes(),offset,subSize);
offset += subSize;
}else {
cache = cipher.doFinal(text.getBytes(),offset,textLength - offset);//开始解密
offset = textLength;
}
System.out.println(cache);
out.write(cache,0,cache.length);
}
byte[] result = out.toByteArray();
out.close();
return Base64.encodeBase64String(result);
}
/**
* 构建RSA密钥对
*
* @return
* @throws NoSuchAlgorithmException
*/
public static RSAKeyPair generateKeyPair() throws NoSuchAlgorithmException {
KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");//KeyPairGenerator用于生成公钥和私钥对,指定生成RSA算法的KeyPairGenerator对象
keyPairGenerator.initialize(1024);//秘钥的长度
KeyPair keyPair = keyPairGenerator.generateKeyPair();//生成密钥对
RSAPublicKey rsaPublicKey = (RSAPublicKey) keyPair.getPublic();//获取公钥
RSAPrivateKey rsaPrivateKey = (RSAPrivateKey) keyPair.getPrivate();//获取私钥
String publicKeyString = Base64.encodeBase64String(rsaPublicKey.getEncoded());//转换为字符串
String privateKeyString = Base64.encodeBase64String(rsaPrivateKey.getEncoded());
RSAKeyPair rsaKeyPair = new RSAKeyPair(privateKeyString, publicKeyString);//存储了私钥和公钥的对象
return rsaKeyPair;
}
}
存储了私钥和公钥的对象
public class RSAKeyPair {
@ApiModelProperty("私钥")
private String privateKey;
@ApiModelProperty("公钥")
private String publicKey;
public RSAKeyPair(String privateKey, String publicKey) {
this.privateKey = privateKey;
this.publicKey = publicKey;
}
}