# Java 端

# 添加如下依赖

<dependency>
    <groupId>commons-codec</groupId>
    <artifactId>commons-codec</artifactId>
    <version>1.13</version>
</dependency>
<dependency>
    <groupId>org.bouncycastle</groupId>
    <artifactId>bcprov-jdk15on</artifactId>
    <version>1.64</version>
</dependency>

# AESCoder

public class AESCoder {

    /**
     * 密钥算法
     */
    public static final String KEY_ALGORITHM = "AES";

    /**
     * 加密/解密算法 /工作模式 /填充方式
     */
    public static final String CIPHER_ALGORITHM = "AES/ECB/PKCS5Padding";

    /**
     * 转换密钥
     *
     * @param key 二进制密钥
     * @return Key 密钥
     */
    private static Key toKey(byte[] key) {
        SecretKey secretKey = new SecretKeySpec(key, KEY_ALGORITHM);
        return secretKey;
    }

    /**
     * 解密
     *
     * @param data 密文
     * @param key  密钥
     * @return byte[] 原文
     * @throws Exception
     */
    public static byte[] decrypt(byte[] data, byte[] key) throws Exception {
        Key k = toKey(key);
        Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM);
        cipher.init(Cipher.DECRYPT_MODE, k);
        return cipher.doFinal(data);
    }

    /**
     * 加密
     *
     * @param data 原文
     * @param key  密钥
     * @return byte[] 密文
     * @throws Exception
     */
    public static byte[] encrypt(byte[] data, byte[] key) throws Exception {
        Key k = toKey(key);
        Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM);
        cipher.init(Cipher.ENCRYPT_MODE, k);
        return cipher.doFinal(data);
    }

}

# AESUtil

public class AESUtil {

    /**
     * AES 加密
     *
     * @param plainText 原文
     * @param key       密钥
     * @return String 密文
     * @throws Exception
     */
    public static String AESEncrypt(String plainText, String key) throws Exception {
        return Base64.encodeBase64String(AESCoder.encrypt(plainText.getBytes(StandardCharsets.UTF_8), key.getBytes(StandardCharsets.UTF_8)));
    }

    /**
     * AES 解密
     *
     * @param cipherText 密文
     * @param key        密钥
     * @return String 原文
     * @throws Exception
     */
    public static String AESDecrypt(String cipherText, String key) throws Exception {
        return new String(AESCoder.decrypt(Base64.decodeBase64(cipherText), key.getBytes(StandardCharsets.UTF_8)), StandardCharsets.UTF_8);
    }
}

# RSACoder

public class RSACoder {

    /**
     * 密钥算法
     */
    public static final String KEY_ALGORITHM = "RSA";

    /**
     * 私钥解密
     *
     * @param data 密文
     * @param key  私钥
     * @return byte[] 原文
     * @throws Exception
     */
    public static byte[] decryptByPrivateKey(byte[] data, byte[] key) throws Exception {
        PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(makePrivateKey(key));
        KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
        PrivateKey privateKey = keyFactory.generatePrivate(pkcs8EncodedKeySpec);
        Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
        cipher.init(Cipher.DECRYPT_MODE, privateKey);
        return cipher.doFinal(data);
    }

    /**
     * 公钥加密
     *
     * @param data 原文
     * @param key  公钥
     * @return byte[] 密文
     * @throws Exception
     */
    public static byte[] encryptByPublicKey(byte[] data, byte[] key) throws Exception {
        X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(key);
        KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
        PublicKey publicKey = keyFactory.generatePublic(x509EncodedKeySpec);
        Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
        cipher.init(Cipher.ENCRYPT_MODE, publicKey);
        return cipher.doFinal(data);
    }

    /**
     * 公钥解密
     *
     * @param data 密文
     * @param key  公钥
     * @return byte[] 原文
     * @throws Exception
     */
    public static byte[] decryptByPublicKey(byte[] data, byte[] key) throws Exception {
        X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(key);
        KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
        PublicKey publicKey = keyFactory.generatePublic(x509EncodedKeySpec);
        Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
        cipher.init(Cipher.DECRYPT_MODE, publicKey);
        return cipher.doFinal(data);
    }

    /**
     * 私钥加密
     *
     * @param data 原文
     * @param key  私钥
     * @return byte[] 密文
     * @throws Exception
     */
    public static byte[] encryptByPrivateKey(byte[] data, byte[] key) throws Exception {
        PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(makePrivateKey(key));
        KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
        PrivateKey privateKey = keyFactory.generatePrivate(pkcs8EncodedKeySpec);
        Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
        cipher.init(Cipher.ENCRYPT_MODE, privateKey);
        return cipher.doFinal(data);
    }

    /**
     * 对私钥进行PKCS8格式化
     *
     * @param data 原始钥匙
     * @return byte[] 格式化后的私钥
     * @throws Exception
     */
    public static byte[] makePrivateKey(byte[] data) throws Exception {
        ASN1EncodableVector asn1EncodableVector1 = new ASN1EncodableVector();
        asn1EncodableVector1.add(new ASN1Integer(0));
        ASN1EncodableVector asn1EncodableVector2 = new ASN1EncodableVector();
        asn1EncodableVector2.add(new ASN1ObjectIdentifier(PKCSObjectIdentifiers.rsaEncryption.getId()));
        asn1EncodableVector2.add(DERNull.INSTANCE);
        asn1EncodableVector1.add(new DERSequence(asn1EncodableVector2));
        asn1EncodableVector1.add(new DEROctetString(data));
        ASN1Sequence sequence = new DERSequence(asn1EncodableVector1);
        return sequence.getEncoded("DER");
    }
}

# RSAUtil

public class RSAUtil {

    /**
     * RSA 公钥加密
     *
     * @param plainText 原文
     * @param key       公钥
     * @return String 密文
     * @throws Exception
     */
    public static String RSAEncryptByPublicKey(String plainText, String key) throws Exception {
        return Base64.encodeBase64String(RSACoder.encryptByPublicKey(plainText.getBytes(StandardCharsets.UTF_8), Base64.decodeBase64(key)));
    }

    /**
     * RSA 私钥解密
     *
     * @param cipherText 密文
     * @param key        私钥
     * @return String 原文
     * @throws Exception
     */
    public static String RSADecryptByPrivateKey(String cipherText, String key) throws Exception {
        return new String(RSACoder.decryptByPrivateKey(Base64.decodeBase64(cipherText), Base64.decodeBase64(key)), StandardCharsets.UTF_8);
    }

    /**
     * RSA 私钥加密
     *
     * @param plainText 原文
     * @param key       私钥
     * @return String 密文
     * @throws Exception
     */
    public static String RSAEncryptByPrivateKey(String plainText, String key) throws Exception {
        return Base64.encodeBase64String(RSACoder.encryptByPrivateKey(plainText.getBytes(StandardCharsets.UTF_8), Base64.decodeBase64(key)));
    }

    /**
     * RSA 公钥解密
     *
     * @param cipherText 密文
     * @param key        公钥
     * @return String 原文
     * @throws Exception
     */
    public static String RSADecryptByPublicKey(String cipherText, String key) throws Exception {
        return new String(RSACoder.decryptByPublicKey(Base64.decodeBase64(cipherText), Base64.decodeBase64(key)), StandardCharsets.UTF_8);
    }
}

# JavaScript 端

# 添加如下依赖

npm install crypto-js
npm install node-rsa

# secret.js

import CryptoJS from "crypto-js";
import NodeRSA from "node-rsa";

/**
 * @return {string}
 */
function AESEncrypt(plainText, key) {
    let encodePlainText = CryptoJS.enc.Utf8.parse(plainText);
    let encodeKey = CryptoJS.enc.Utf8.parse(key);
    let encryptedData = CryptoJS.AES.encrypt(encodePlainText, encodeKey, {
        mode: CryptoJS.mode.ECB,
        padding: CryptoJS.pad.Pkcs7
    });
    return encryptedData.ciphertext.toString(CryptoJS.enc.Base64);
}

/**
 * @return {string}
 */
function AESDecrypt(cipherText, key) {
    let encodeKey = CryptoJS.enc.Utf8.parse(key);
    let decryptedData = CryptoJS.AES.decrypt(cipherText, encodeKey, {
        mode: CryptoJS.mode.ECB,
        padding: CryptoJS.pad.Pkcs7
    });
    return decryptedData.toString(CryptoJS.enc.Utf8);

}

const privateKey = new NodeRSA("-----BEGIN RSA PRIVATE KEY-----\n" +
    "MIICWwIBAAKBgQCv/YEH5BiuSkblVJ71ZXaiuKaBz5QW5JB05flVEZPX4Kaiw8Cs\n" +
    "K/TRHCflO8aPvRUwVaExe0ZtsXMQ72ohuhk8eJQayq6DGHc12C8fddBFWo8YFP1j\n" +
    "XPL68pux6g14hB6vjmSntcsC4SBOcCf+esZKlj/t6LUkp/5othjsag9G9wIDAQAB\n" +
    "AoGAeaC8xSRZ/lJtLt9NwJEv7YOp57r7QNsUDwZFTAqK375ty7138kWqu742wFGQ\n" +
    "iBSIiVAUyCrHYNYrjP+5nLeN6jwxY5Z4WprSjTlKisDDxJrcSIKJ49qNNNx6lyiQ\n" +
    "bOZbMf/WQWxBZE7BTKQ3JykdhRVta/NE+E+4fez2crGr4AECQQDfYShcmOPagGH/\n" +
    "kKpeOpk5HV5siKQeI6UcXzdFNq+i7nezAZRJK2pTIvizu4e+AlI+/QNDFYpFW0vr\n" +
    "Rw2Cx5ABAkEAybC9uC2Ry3O1y38Du2ynMVx0TtQhJIWOZ5xs4VR6lR88wGKzjPuQ\n" +
    "Qa1lK0GysAKzk+8GszSzrKtYCmAbgSNW9wJAcxU3Gh2apiOmWWhKnalK72X2E6yC\n" +
    "ARUUJ33Wl84IxsRc3thdcSTw7kwCHXbsBDRl8xWe7JzYU8spXdmJWGtAAQJABVSK\n" +
    "bwelRr80GsCslJN2h7Ntz3eDuLde4BYeOoZFBxPgQyVYoW00jsfKWK5Pzp8Dp/E1\n" +
    "OB84cGPG299WWr9YWQJALjf2Hjb70DN/en9oQl/FRVK4pSIVy+E9CwWoH7BZWtiS\n" +
    "6v4tK8q/a08avnaAvkNQIqK3S1DN/OJiyhXdcdNuiw==\n" +
    "-----END RSA PRIVATE KEY-----");

const publicKey = new NodeRSA("-----BEGIN PUBLIC KEY-----\n" +
    "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCv/YEH5BiuSkblVJ71ZXaiuKaB\n" +
    "z5QW5JB05flVEZPX4Kaiw8CsK/TRHCflO8aPvRUwVaExe0ZtsXMQ72ohuhk8eJQa\n" +
    "yq6DGHc12C8fddBFWo8YFP1jXPL68pux6g14hB6vjmSntcsC4SBOcCf+esZKlj/t\n" +
    "6LUkp/5othjsag9G9wIDAQAB\n" +
    "-----END PUBLIC KEY-----");

privateKey.setOptions({encryptionScheme: "pkcs1"});
publicKey.setOptions({encryptionScheme: "pkcs1"});

function RSAEncryptByPublicKey(plainText) {
    return publicKey.encrypt(plainText, "base64", "utf8");
}

function RSADecryptByPrivateKey(cipherText) {
    return privateKey.decrypt(cipherText, "utf8");
}

function RSAEncryptByPrivateKey(plainText) {
    return privateKey.encryptPrivate(plainText, "base64", "utf8");
}

function RSADecryptByPublicKey(cipherText) {
    return publicKey.decryptPublic(cipherText, "utf8");
}

export default {
    AESEncrypt,
    AESDecrypt,
    RSAEncryptByPublicKey,
    RSADecryptByPrivateKey,
    RSAEncryptByPrivateKey,
    RSADecryptByPublicKey
}

# 注意事项

JavaScript 端密钥包括类似 “-----BEGIN PUBLIC KEY-----” 部分。

Java 端密钥不包括类似 “-----BEGIN PUBLIC KEY-----” 部分。

通过字符串指定密钥长度为所需密钥长度除以 8。(bit->byte)

# RSA 密钥生成方式

// 进入openssl
openssl
// 生成私钥
genrsa -out rsa_private_key.pem 1024
// 生成私钥对应的公钥
rsa -in rsa_private_key.pem -pubout -out rsa_public_key.pem