# 前端
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); | |
} | |
} |