Java和JavaScript(CryptoJS)的AES互相加解密实现

Java和JavaScript(CryptoJS)的AES互相加解密实现

一、Java 后端

java后端代码采用jdk提供的加解密算法实现(中间穿插了部分其他库的工具类apache-common),异常捕获那块还可以细化!(转载请标明来源!!!!!!!!!!)

1.1 java代码实现

import org.apache.commons.lang3.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;
import java.security.SecureRandom;
/**
 * @author 桔梗迷
 * @date 2023/10/19 14:35
 */
public class AesUtil {

    private static final Log log = LogFactory.getLog(AesUtil.class);

    private static final java.util.Base64.Encoder ENCODER = java.util.Base64.getEncoder();
    private static final java.util.Base64.Decoder DECODER = java.util.Base64.getDecoder();

    /**
     * 默认key 16位byte[] [106, -26, -43, -79, -22, 11, -49, 112, 100, -111, -27, -54, 9, 115, 115, 50]
     */
    private static final String DEFAULT_KEY = "aubVseoLz3BkkeXKCXNzMg==";
    /**
     * 默认向量 16位byte[] {25, 101, -116, -100, 98, 100, -125, 126, -57, -26, 3, 107, -45, 79, -34, -19}
     */
    public static final String DEFAULT_IV = "GWWMnGJkg37H5gNr00/e7Q==";

    /**
     * 对称加密
     *
     * @param plainText 明文
     */
    public static String encrypt(String plainText) throws Exception {
        return encrypt(plainText, DEFAULT_KEY);
    }

    /**
     * 对称加密
     *
     * @param key       密钥
     * @param plainText 明文
     */
    public static String encrypt(String plainText, String key) throws Exception {
        return encrypt(plainText, key, DEFAULT_IV);
    }

    /**
     * 对称加密
     *
     * @param secretKey 密钥
     * @param iv        加密向量,只有CBC模式才支持
     * @param plainText 明文
     */
    public static String encrypt(String plainText, String secretKey, String iv) throws Exception {
        if (StringUtils.isAnyEmpty(plainText, secretKey, iv)) {
            log.error("存在空值!!");
            return null;
        }
        SecretKey key = new SecretKeySpec(DECODER.decode(secretKey), "AES");
        byte[] plainTextInBytes = plainText.getBytes(StandardCharsets.UTF_8);
        Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
        cipher.init(Cipher.ENCRYPT_MODE, key, new IvParameterSpec(DECODER.decode(iv)));
        return ENCODER.encodeToString(cipher.doFinal(plainTextInBytes));
    }

    /**
     * 对称解密
     *
     * @param cipherText 密文
     */
    public static String decrypt(String cipherText) throws Exception {
        return decrypt(cipherText, DEFAULT_KEY);
    }

    /**
     * 对称解密
     *
     * @param key        密钥
     * @param cipherText 密文
     */
    public static String decrypt(String cipherText, String key) throws Exception {
        return decrypt(cipherText, key, DEFAULT_IV);
    }

    /**
     * 对称解密
     *
     * @param secretKey  密钥
     * @param iv         加密向量(需要16位byte数组字符串),只有CBC模式才支持
     * @param ciphertext 密文
     */
    public static String decrypt(String ciphertext, String secretKey, String iv) throws Exception {
        if (StringUtils.isAnyEmpty(ciphertext, secretKey, iv)) {
            log.error("存在空值!!");
            return null;
        }
        SecretKey key = new SecretKeySpec(DECODER.decode(secretKey), "AES");
        IvParameterSpec ivParameterSpec = new IvParameterSpec(DECODER.decode(iv));
        byte[] ciphertextInBytes = DECODER.decode(ciphertext);
        Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
        cipher.init(Cipher.DECRYPT_MODE, key, ivParameterSpec);
        return new String(cipher.doFinal(ciphertextInBytes), StandardCharsets.UTF_8);
    }


    public static void main(String[] args) throws Exception {
        String str = "hello word!";
        String pwd = encrypt(str);
        System.out.println("密文字符串1:" + pwd);
        System.out.println(decrypt(pwd));
        System.out.println("----------------------------");
        byte[] bytes = new SecureRandom().generateSeed(16);
        String key = ENCODER.encodeToString(bytes);
        System.out.println("key2:");
        pwd = encrypt(str, key);
        System.out.println("密文字符串2:" + pwd);
        System.out.println(decrypt(pwd, key));
        System.out.println("----------------------------");
        byte[] keyArr = new SecureRandom().generateSeed(16);
        byte[] ivArr = new SecureRandom().generateSeed(16);
        key = ENCODER.encodeToString(keyArr);
        String iv = ENCODER.encodeToString(ivArr);
        pwd = encrypt(str, key, iv);
        System.out.println("key3:" + key);
        System.out.println("iv3:" + iv);
        System.out.println("密文字符串3:" + pwd);
        System.out.println(decrypt(pwd, key, iv));
    }
}

1.2 java测试结果

在这里插入图片描述

二、JavaScript前端

js端使用crypto-js实现 github仓库地址 https://github.com/brix/crypto-js/releases/tag/4.1.1

2.1 JavaScript代码

这里我直接下载源码然后新建个html页面测试

<body>
    <script type="text/javascript" src="../crypto-js-4.1.1/crypto-js.js"></script>
    <script type="text/javascript" src="../crypto-js-4.1.1/aes.js"></script>
    <script type="text/javascript" src="../crypto-js-4.1.1/crypto-js.js"></script>
    <script type="text/javascript">
        function encryptByAES(plainText, keyInBase64Str, ivInBase64Str) {
            let key = CryptoJS.enc.Base64.parse(keyInBase64Str)
            let iv = CryptoJS.enc.Base64.parse(ivInBase64Str)
            let encrypted = CryptoJS.AES.encrypt(plainText, key, {
                iv: iv,
                mode: CryptoJS.mode.CBC,
                padding: CryptoJS.pad.Pkcs7
            })
            return encrypted.ciphertext.toString(CryptoJS.enc.Base64)
        }

        function decryptByAES(cipherText, keyInBase64Str, ivInBase64Str) {
            let key = CryptoJS.enc.Base64.parse(keyInBase64Str)
            let iv = CryptoJS.enc.Base64.parse(ivInBase64Str)
            // 返回的是一个Word Array Object,其实就是Java里的字节数组
            let decrypted = CryptoJS.AES.decrypt(cipherText, key, {
                iv: iv,
                mode: CryptoJS.mode.CBC,
             padding: CryptoJS.pad.Pkcs7
            })
        return decrypted.toString(CryptoJS.enc.Utf8)
        }
    </script>
</body>

2.2 测试结果

我是在浏览器的控制台进行的测试

2.2.1 js对java的密文字符串进行解密

在这里插入图片描述

2.2.2 js加密java解密

在这里插入图片描述
在这里插入图片描述

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,这是一个常见的加密解密场景。你可以使用以下步骤进行加密和解密: 1. 在 JavaScript 中使用 AES 加密文本,例如使用 CryptoJS 库。 ```javascript var key = CryptoJS.enc.Utf8.parse("Secret Passphrase"); // 使用加密密钥 var iv = CryptoJS.enc.Utf8.parse("Initialization Vector"); // 使用初始化向量 var encrypted = CryptoJS.AES.encrypt("Hello World!", key, { iv: iv }); // 加密数据 var encryptedText = encrypted.toString(); ``` 2. 将加密后的文本发送到后端,使用 Java 进行解密,例如使用 Bouncy Castle 库。 ```java import org.bouncycastle.jce.provider.BouncyCastleProvider; import javax.crypto.Cipher; import javax.crypto.spec.IvParameterSpec; import javax.crypto.spec.SecretKeySpec; import java.security.Security; public class AesUtil { public static String decrypt(String encryptedText, String key, String iv) { Security.addProvider(new BouncyCastleProvider()); try { byte[] keyBytes = key.getBytes("UTF-8"); byte[] ivBytes = iv.getBytes("UTF-8"); byte[] encryptedBytes = Base64.getDecoder().decode(encryptedText); Cipher cipher = Cipher.getInstance("AES/CBC/PKCS7Padding", "BC"); SecretKeySpec secretKeySpec = new SecretKeySpec(keyBytes, "AES"); IvParameterSpec ivParameterSpec = new IvParameterSpec(ivBytes); cipher.init(Cipher.DECRYPT_MODE, secretKeySpec, ivParameterSpec); byte[] decryptedBytes = cipher.doFinal(encryptedBytes); return new String(decryptedBytes, "UTF-8"); } catch (Exception ex) { ex.printStackTrace(); return null; } } } ``` 3. 在 Java 中调用 `AesUtil.decrypt()` 方法进行解密。 ```java String encryptedText = "U2FsdGVkX1+4kg4xJ0TZx8M1m3B0i3WrJHv5QSwz5vU="; String key = "Secret Passphrase"; String iv = "Initialization Vector"; String decryptedText = AesUtil.decrypt(encryptedText, key, iv); System.out.println(decryptedText); // 输出 "Hello World!" ``` 请注意,这只是一个基本的示例,你需要根据你的具体情况进行调整。此外,确保保护好你的加密密钥和初始化向量,以确保安全性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值