# 前端

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);
    }
}