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