(blog.csdn.net/qq_31856061…)
依赖
<dependency>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
<version>1.12</version>
</dependency>
工具类
import org.apache.commons.codec.binary.Base64
import java.io.ByteArrayOutputStream
import java.security.Key
import java.security.KeyFactory
import java.security.KeyPair
import java.security.KeyPairGenerator
import java.security.PrivateKey
import java.security.PublicKey
import java.security.Signature
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
/** */
/**
* <p>
* RSA公钥/私钥/签名工具包
* </p>
* <p>
* 罗纳德·李维斯特(Ron [R]ivest)、阿迪·萨莫尔(Adi [S]hamir)和伦纳德·阿德曼(Leonard [A]dleman)
* </p>
* <p>
* 字符串格式的密钥在未在特殊说明情况下都为BASE64编码格式<br/>
* 由于非对称加密速度极其缓慢,一般文件不使用它来加密而是使用对称加密,<br/>
* 非对称加密算法可以用来对对称加密的密钥加密,这样保证密钥的安全也就保证了数据的安全
* </p>
*/
public class RSAUtils {
/**
* 加密算法RSA
*/
public static final String KEY_ALGORITHM = "RSA"
/**
* 签名算法
*/
public static final String SIGNATURE_ALGORITHM = "MD5withRSA"
/**
* 获取公钥的key
*/
private static final String PUBLIC_KEY = "RSAPublicKey"
/**
* 获取私钥的key
*/
private static final String PRIVATE_KEY = "RSAPrivateKey"
/**
* RSA最大加密明文大小
*/
private static final int MAX_ENCRYPT_BLOCK = 117
/**
* RSA最大解密密文大小
*/
private static final int MAX_DECRYPT_BLOCK = 128
/**
* RSA 位数 如果采用2048 上面最大加密和最大解密则须填写: 245 256
*/
private static final int INITIALIZE_LENGTH = 1024
/**
* 生成密钥对(公钥和私钥)
*/
public static Map<String, Object> genKeyPair() throws Exception {
KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance(KEY_ALGORITHM)
keyPairGen.initialize(INITIALIZE_LENGTH)
KeyPair keyPair = keyPairGen.generateKeyPair()
RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic()
RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate()
Map<String, Object> keyMap = new HashMap<String, Object>(2)
keyMap.put(PUBLIC_KEY, publicKey)
keyMap.put(PRIVATE_KEY, privateKey)
return keyMap
}
/**
* 用私钥对信息生成数字签名
* @param encryptedData 已加密数据
* @param publicKey 公钥(BASE64编码)
*/
public static String sign(byte[] data, String privateKey) throws Exception {
byte[] keyBytes = Base64.decodeBase64(privateKey)
PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes)
KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM)
PrivateKey privateK = keyFactory.generatePrivate(pkcs8KeySpec)
Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM)
signature.initSign(privateK)
signature.update(data)
return Base64.encodeBase64String(signature.sign())
}
/**
* 校验数字签名
* @param encryptedData 已加密数据
* @param publicKey 公钥(BASE64编码)
*/
public static boolean verify(byte[] data, String publicKey, String sign) throws Exception {
byte[] keyBytes = Base64.decodeBase64(publicKey)
X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes)
KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM)
PublicKey publicK = keyFactory.generatePublic(keySpec)
Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM)
signature.initVerify(publicK)
signature.update(data)
return signature.verify(Base64.decodeBase64(sign))
}
/**
* 私钥解密
* @param encryptedData 已加密数据
* @param publicKey 公钥(BASE64编码)
*/
public static byte[] decryptByPrivateKey(byte[] encryptedData, String privateKey) throws Exception {
byte[] keyBytes = Base64.decodeBase64(privateKey)
PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes)
KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM)
Key privateK = keyFactory.generatePrivate(pkcs8KeySpec)
Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm())
cipher.init(Cipher.DECRYPT_MODE, privateK)
int inputLen = encryptedData.length
ByteArrayOutputStream out = new ByteArrayOutputStream()
int offSet = 0
byte[] cache
int i = 0
// 对数据分段解密
while (inputLen - offSet > 0) {
if (inputLen - offSet > MAX_DECRYPT_BLOCK) {
cache = cipher.doFinal(encryptedData, offSet, MAX_DECRYPT_BLOCK)
} else {
cache = cipher.doFinal(encryptedData, offSet, inputLen - offSet)
}
out.write(cache, 0, cache.length)
i++
offSet = i * MAX_DECRYPT_BLOCK
}
byte[] decryptedData = out.toByteArray()
out.close()
return decryptedData
}
/**
* 公钥解密
* @param encryptedData 已加密数据
* @param publicKey 公钥(BASE64编码)
*/
public static byte[] decryptByPublicKey(byte[] encryptedData, String publicKey) throws Exception {
byte[] keyBytes = Base64.decodeBase64(publicKey)
X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes)
KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM)
Key publicK = keyFactory.generatePublic(x509KeySpec)
Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm())
cipher.init(Cipher.DECRYPT_MODE, publicK)
int inputLen = encryptedData.length
ByteArrayOutputStream out = new ByteArrayOutputStream()
int offSet = 0
byte[] cache
int i = 0
// 对数据分段解密
while (inputLen - offSet > 0) {
if (inputLen - offSet > MAX_DECRYPT_BLOCK) {
cache = cipher.doFinal(encryptedData, offSet, MAX_DECRYPT_BLOCK)
} else {
cache = cipher.doFinal(encryptedData, offSet, inputLen - offSet)
}
out.write(cache, 0, cache.length)
i++
offSet = i * MAX_DECRYPT_BLOCK
}
byte[] decryptedData = out.toByteArray()
out.close()
return decryptedData
}
/** */
/**
* 公钥加密
* @param data 源数据
* @param privateKey 私钥(BASE64编码)
*/
public static byte[] encryptByPublicKey(byte[] data, String publicKey) throws Exception {
byte[] keyBytes = Base64.decodeBase64(publicKey)
X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes)
KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM)
Key publicK = keyFactory.generatePublic(x509KeySpec)
// 对数据加密
Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm())
cipher.init(Cipher.ENCRYPT_MODE, publicK)
int inputLen = data.length
ByteArrayOutputStream out = new ByteArrayOutputStream()
int offSet = 0
byte[] cache
int i = 0
// 对数据分段加密
while (inputLen - offSet > 0) {
if (inputLen - offSet > MAX_ENCRYPT_BLOCK) {
cache = cipher.doFinal(data, offSet, MAX_ENCRYPT_BLOCK)
} else {
cache = cipher.doFinal(data, offSet, inputLen - offSet)
}
out.write(cache, 0, cache.length)
i++
offSet = i * MAX_ENCRYPT_BLOCK
}
byte[] encryptedData = out.toByteArray()
out.close()
return encryptedData
}
/**
* 私钥加密
* @param data 源数据
* @param privateKey 私钥(BASE64编码)
*/
public static byte[] encryptByPrivateKey(byte[] data, String privateKey) throws Exception {
byte[] keyBytes = Base64.decodeBase64(privateKey)
PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes)
KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM)
Key privateK = keyFactory.generatePrivate(pkcs8KeySpec)
Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm())
cipher.init(Cipher.ENCRYPT_MODE, privateK)
int inputLen = data.length
ByteArrayOutputStream out = new ByteArrayOutputStream()
int offSet = 0
byte[] cache
int i = 0
// 对数据分段加密
while (inputLen - offSet > 0) {
if (inputLen - offSet > MAX_ENCRYPT_BLOCK) {
cache = cipher.doFinal(data, offSet, MAX_ENCRYPT_BLOCK)
} else {
cache = cipher.doFinal(data, offSet, inputLen - offSet)
}
out.write(cache, 0, cache.length)
i++
offSet = i * MAX_ENCRYPT_BLOCK
}
byte[] encryptedData = out.toByteArray()
out.close()
return encryptedData
}
/**
* 获取私钥
* @param keyMap 密钥对
*/
public static String getPrivateKey(Map<String, Object> keyMap) throws Exception {
Key key = (Key) keyMap.get(PRIVATE_KEY)
return Base64.encodeBase64String(key.getEncoded())
}
/**
* 获取公钥
* @param keyMap 密钥对
*/
public static String getPublicKey(Map<String, Object> keyMap) throws Exception {
Key key = (Key) keyMap.get(PUBLIC_KEY)
return Base64.encodeBase64String(key.getEncoded())
}
/**
* java端公钥加密
*/
public static String encryptedDataOnJava(String data, String PUBLICKEY) {
try {
data = Base64.encodeBase64String(encryptByPublicKey(data.getBytes(), PUBLICKEY))
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace()
}
return data
}
/**
* java端私钥解密
*/
public static String decryptDataOnJava(String data, String PRIVATEKEY) {
String temp = ""
try {
byte[] rs = Base64.decodeBase64(data)
temp = new String(RSAUtils.decryptByPrivateKey(rs, PRIVATEKEY),"UTF-8")
} catch (Exception e) {
e.printStackTrace()
}
return temp
}
public static void main(String[] args) throws Exception{}
}
测试工具类创建密钥对
public class RSAUtilsTest {
@Test
public void genKeyPair() throws Exception {
Map<String, Object> map = RSAUtils.genKeyPair();
String publicKey = RSAUtils.getPublicKey(map);
String privateKey = RSAUtils.getPrivateKey(map);
System.out.println("publicKey = " + publicKey);
System.out.println("privateKey = " + privateKey);
}
}
前端加密
npm i -S jsencrypt
import { JSEncrypt } from "jsencrypt";
const publicKey = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCAjZxdeSIZvA4WNWkqzfCYocOr7o1FZsEFfYTiLYSP5A9ECojwf3Wx8JTAmSRecNgJufFgfgAFdujtO59LKoV7dPRXdRTs0cplHZesDF/TjrJUQVcwaUqEWumL5IxEoHvzQgiTuoeuAmQVl8zuaNWyCiskshD9wp5i+tP4cj1yAQIDAQAB";
const jsEncrypt = new JSEncrypt();
jsEncrypt.setPublicKey(publicKey);
function encrypt(str) {
return jsEncrypt.encrypt(str);
}