使用CryptoJS解码(Base64)和Decrypt(AES/CBC/PKCS5PADDING) - React

sam*_*hah 7 encryption base64 decode aes cryptojs

我正在使用react作为前端和spring mvc作为后端的Web应用程序.我需要将一些用户信息存储在浏览器的本地存储中.我不想将该信息作为纯文本存储在本地存储中.所以我想在服务器端进行AES加密并将这些数据推回到JS端.为此,我需要客户端解密框架.我发现crypto-js对所有这些都非常有用.我无法理解客户端缺少解密和解码的地方.

我首先解释我的Spring Side Encryption Code,这绝对没问题:

public class EncryptDecrypt {

        private static final String SECRET_KEY_1 = "ssdkF$HUy2A#D%kd";
        private static final String SECRET_KEY_2 = "weJiSEvR5yAC5ftB";

        private IvParameterSpec ivParameterSpec;
        private SecretKeySpec secretKeySpec;
        private Cipher cipher;

        public EncryptDecrypt() throws UnsupportedEncodingException, NoSuchPaddingException, NoSuchAlgorithmException {
            ivParameterSpec = new IvParameterSpec(SECRET_KEY_1.getBytes("UTF-8"));
            secretKeySpec = new SecretKeySpec(SECRET_KEY_2.getBytes("UTF-8"), "AES");
            cipher = Cipher.getInstance("AES/CBC/PKCS5PADDING");
        }

        public String encrypt(String toBeEncrypt) throws NoSuchPaddingException, NoSuchAlgorithmException, 
            InvalidAlgorithmParameterException, InvalidKeyException, BadPaddingException, IllegalBlockSizeException {
            cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec, ivParameterSpec);
            byte[] encrypted = cipher.doFinal(toBeEncrypt.getBytes());
            return Base64.encodeBase64String(encrypted);
        }
}
Run Code Online (Sandbox Code Playgroud)

在客户端,我无法用简单的事情解码和解密代码.这是我的客户端代码:

var CryptoJS = require("crypto-js");

var data = "Ggydx4oA1+SKBw+unA8BUUm2tnvkQbp1terdF2PEGFYSEZL/ye08op/0b0BauGtIl1dBIodrlKXo2de3MykYmocd3ctxFtIIki01V+M8XeQj6B384o0G+H7NpVx5tCJjPDvdqVRObtxCTqu3r8QRzYTNcMM5bRhbYxCYl8/NRyPQJnmcJDlRBeVOoJiQNA7Qd5UJD/mNivoyMUfYGV7/DlpylQWWwEAHVdgcb865i8jnf3vqURehAXYoaD6Bgodi1EM4H007uv0o6NEOk3H4jQ==";

var key = "weJiSEvR5yAC5ftB";

// Decode the base64 data so we can separate iv and crypt text.
var rawData = atob(data);
var iv = "ssdkF$HUy2A#D%kd";
var crypttext = rawData.substring(16);

console.log(rawData);

// Decrypt...
var plaintextArray = CryptoJS.AES.decrypt(
  { ciphertext: CryptoJS.enc.Base64.parse(crypttext) },
  key,
  { iv: iv }
);

console.log(plaintextArray);

console.log(CryptoJS.enc.Base64.stringify(plaintextArray));

var decryptedData = JSON.parse(CryptoJS.enc.Base64.stringify(plaintextArray).toString(CryptoJS.enc.Utf8));

console.log(decryptedData);
Run Code Online (Sandbox Code Playgroud)

PS:我已经将JSON发送到客户端,所以我最终解析它.我是加密和解密的新手.我真的很困惑我的客户端代码应该是什么样子.请帮忙.

Zer*_*tul 6

您不应该将字符串作为 中的键传递CryptoJS。在这种情况下,它不认为该字符串是密钥,而是密码。并通过使用从密码生成密钥PBKDF。下面的工作示例:

var data = "Ggydx4oA1+SKBw+unA8BUUm2tnvkQbp1terdF2PEGFYSEZL/ye08op/0b0BauGtIl1dBIodrlKXo2de3MykYmocd3ctxFtIIki01V+M8XeQj6B384o0G+H7NpVx5tCJjPDvdqVRObtxCTqu3r8QRzYTNcMM5bRhbYxCYl8/NRyPQJnmcJDlRBeVOoJiQNA7Qd5UJD/mNivoyMUfYGV7/DlpylQWWwEAHVdgcb865i8jnf3vqURehAXYoaD6Bgodi1EM4H007uv0o6NEOk3H4jQ==";
var rawData = CryptoJS.enc.Base64.parse(data);
var key = CryptoJS.enc.Latin1.parse("weJiSEvR5yAC5ftB");
var iv = CryptoJS.enc.Latin1.parse("ssdkF$HUy2A#D%kd");
var plaintextData = CryptoJS.AES.decrypt(
    { ciphertext: rawData },
    key,
    { iv: iv });
var plaintext = plaintextData.toString(CryptoJS.enc.Latin1);
console.log(plaintext);
Run Code Online (Sandbox Code Playgroud)
<script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/3.1.9-1/crypto-js.js"></script>
Run Code Online (Sandbox Code Playgroud)

顺便说一句,您不应该每次都使用相同的 IV。在这种情况下,您就错过了 IV 和 CBC 模式的基本目的。您的整体安全性变得与 ECB 模式相同。