前端
1.引入jsencrypt
# 使用npm引入
cnpm install jsencrypt
2.创建通用的工具JS
公钥可以通过此网站在线生成 在线生成公钥私钥对
示例代码使用的密码格式:
- 密钥长度:1024 bit
- 密钥格式:PKCS#8
注意:当使用IDE将密钥转换成一行时,小心换行符,有的IDE不显示。此时可以将文本粘贴到Chrome Console检查!
import { JSEncrypt } from 'jsencrypt'
/**
* 公钥是通过base64加密转化的
* 默认的公钥,用于登录密码的加密.
*/
var publicKey = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC4jFr2m2d0AWFhmHs23LcW6649tZUk+7vxPjHW+/YZeCgXi8x9ANK0BGt8Kji8Ujc+K+YU7oLU0AlMoXzG05/Ghc7GNfLBb0tv2hYMYFKzctYR8tHGv0Zxp1nV0AJYiZKqW+v9WTWvfFMs1MOshADkTk9qHDpsxUYMy8CU6j09MQIDAQAB"
/**
* RSA 加密封装
* @param {需要加密的数据} data
* @returns
*/
export function encrypt(data) {
var jsEncrypt = new JSEncrypt();
jsEncrypt.setPublicKey(publicKey);
return jsEncrypt.encrypt(data);
}
Java
package com.demo.utils;
import lombok.SneakyThrows;
import org.apache.commons.codec.binary.Base64;
import javax.crypto.Cipher;
import java.io.ByteArrayOutputStream;
import java.security.KeyFactory;
import java.security.PrivateKey;
import java.security.spec.PKCS8EncodedKeySpec;
/**
* RSA加密算法工具类
*
* @author utrix
* @date 2021/11/16
*/
public final class RSAUtil {
/**
* RSA最大解密密文大小
*/
private static final int MAX_DECRYPT_BLOCK = 128;
/**
* 获取私钥
*
* @param privateKey 私钥字符串
* @return {@link PrivateKey}
*/
@SneakyThrows
public static PrivateKey getPrivateKey(String privateKey) {
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
byte[] decodedKey = Base64.decodeBase64(privateKey.getBytes());
PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(decodedKey);
return keyFactory.generatePrivate(keySpec);
}
/**
* RSA解密
*
* @param data 待解密数据
* @param privateKey 私钥
* @return {@link String} 解密好的字符串
*/
@SneakyThrows
public static String decrypt(String data, PrivateKey privateKey) {
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.DECRYPT_MODE, privateKey);
byte[] dataBytes = Base64.decodeBase64(data);
int inputLen = dataBytes.length;
int offset = 0;
byte[] cache;
int i = 0;
try (ByteArrayOutputStream out = new ByteArrayOutputStream()) {
// 对数据分段解密
while (inputLen - offset > 0) {
if (inputLen - offset > MAX_DECRYPT_BLOCK) {
cache = cipher.doFinal(dataBytes, offset, MAX_DECRYPT_BLOCK);
} else {
cache = cipher.doFinal(dataBytes, offset, inputLen - offset);
}
out.write(cache, 0, cache.length);
i++;
offset = i*MAX_DECRYPT_BLOCK;
}
// 解密后的内容
return out.toString("UTF-8");
}
}
private RSAUtil() {}
}
测试
package com.unionstone.fny.utils;
import org.junit.jupiter.api.Test;
import java.security.PrivateKey;
class RSAUtilTest {
// 与前端一块生成的公钥私钥对。此为私钥(此为示例值,已被和谐不可直接复用)
private static final String PRIVATE_KEY = "MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBAKZg2Fp+4sy1lTRvcfjSXkZRPtf6F8aZTVVOnEgCucJ2cgbo52Eg/EWRHTVBXQ+YhqV3vmMBbrau/hv+JjDR2hx9dcMjEQ1AuaOok9oxgDHVPoSJEC/7FsEULyMXSYgf0In/fBtsCZmtp6lvvOeBRvexhkoGVXaIenasnroa07PzAgMBAAECgYA4XIxOM7eu80BlL++jA9it523riiwtutBr4/1Fmq6zRxbEAROWIHNLiyC6Z/66hYJ71EpcCQmV8D99Mvp0z4CrNLAkEAzQ3T1zaDJRiwXGRHcBOHhqBNtt8X+IjEKLPdOJOHiS5fuNVZ1Ax5DkfewInsjMKmzr+Bd8SjxrX9hMK2FtCZwQJADzCln/vG4k2NPOg8L8CNPgoITQF2wFdDJpmGOv6vf/Q+7RDx5pqddvJsPFI3AIAGarQ1ds437pVyAK89racjAQJBAK0gOJYnIgZG1IEOdSTemVDsW7eYZ3eQVw2xnMgZvQQJdxlvWaLgzpvanjNwreE0ZP/NCaCZCc0LGN2bDJuFIpg=";
@Test
void decrypt() {
// 前端加密的密钥
String ciphertext = "xxxx";
PrivateKey privateKey = RSAUtil.getPrivateKey(PRIVATE_KEY);
String decrypt = RSAUtil.decrypt(ciphertext, privateKey);
System.out.println(decrypt);
}
}