如何在 Crypto JS 中为邮递员实现 AES 128

How to implement AES 128 in Crypto JS for postman

我有这个 C# 代码:

    public string Encrypt( string aesKey)
    {            
        var data = "ASD_POC";
        var aesKey = "OxLDVPTHLk5EHR5AE8O0rg==";            
        var token = Encoding.UTF8.GetBytes(data);
        byte[] _key = Convert.FromBase64String(aesKey);
        string retnResult = string.Empty;
        AesCryptoServiceProvider aesProvider = new System.Security.Cryptography.AesCryptoServiceProvider();
        MemoryStream memStream = null;
        CryptoStream cryptoStream = null;
        System.Net.ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
        byte[] cipherText;

        try
        {
            aesProvider.Mode = CipherMode.CBC;
            aesProvider.Padding = PaddingMode.PKCS7;
            aesProvider.BlockSize = 128;
            aesProvider.KeySize = 128;
            aesProvider.GenerateIV();
            memStream = new MemoryStream();
            cryptoStream = new CryptoStream(memStream, aesProvider.CreateEncryptor(_key, aesProvider.IV), CryptoStreamMode.Write);
            cryptoStream.Write(token, 0, token.Length);
            cryptoStream.FlushFinalBlock();
            cipherText = memStream.ToArray();
            var combinedIvCipherText = new byte[aesProvider.IV.Length + cipherText.Length];
            Array.Copy(aesProvider.IV, 0, combinedIvCipherText, 0, aesProvider.IV.Length);
            Array.Copy(cipherText, 0, combinedIvCipherText, aesProvider.IV.Length, cipherText.Length);
            retnResult = Convert.ToBase64String(combinedIvCipherText);
        }

我已尝试为 Postman 集合实现此功能:

var CryptoJS = require("crypto-js");
// Generate random 16 bytes to use as IV
var IV = CryptoJS.lib.WordArray.random(16);

var data = "ASD_POC";
var aesKey = "OxLDVPTHLk5EHR5AE8O0rg=="; 

var tokenData = atob(aesKey);
var Key = Uint8Array.from(tokenData, b => b.charCodeAt(0));

function encrypt(data) {
    var val = CryptoJS.enc.Utf8.parse(data);
    var encrypted = CryptoJS.AES.encrypt(
        val, 
        Key, 
        { 
            iv: IV,
            mode: CryptoJS.mode.CBC,
            padding: CryptoJS.pad.Pkcs7,
            keySize: 128,
            BlockSize: 128
        }).toString();
        console.log(encrypted);
    var b64 = CryptoJS.enc.Base64.parse(encrypted).toString(CryptoJS.enc.Hex);
    
    console.log(b64)    
    return b64;
}

但是当我尝试从 CryptoJs 进行字符串化时 - 我收到了一个错误,我不能。 我在实施中做错了什么?我尝试 google 更多关于 CryptoJs 的信息 - 但找不到更多信息 than 而且它不包含很多信息。

CryptoJS 代码缺少 IV 和密文的串联。

此外,在某些情况下使用了错误的编码。 CryptoJS 使用 WordArrays 并提供不同的 encoders 来转换为这种类型。

CryptoJS 的可能实现是:

var data = "ASD_POC";
var aesKey = "OxLDVPTHLk5EHR5AE8O0rg=="; 
var ivWA = CryptoJS.lib.WordArray.random(16);
//var ivWA = CryptoJS.enc.Hex.parse("2423c5414ead3812e68a799c8c6deab7"); //for testing only
function encrypt(data, aesKey) {
    var dataWA = CryptoJS.enc.Utf8.parse(data);
    var keyWA = CryptoJS.enc.Base64.parse(aesKey);
    var ciphertext = CryptoJS.AES.encrypt(dataWA, keyWA, {iv: ivWA}).ciphertext;
    var ivCiphertext = ivWA.clone().concat(ciphertext);
    var ivCiphertextB64 = ivCiphertext.toString(CryptoJS.enc.Base64);
    return ivCiphertextB64;
}

document.getElementById("ct").innerHTML = encrypt(data, aesKey); 
<script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/4.0.0/crypto-js.min.js"></script>
<p style="font-family:'Courier New', monospace;" id="ct"></p>

作为测试,可以使用 C# 代码创建密文,例如JCPFQU6tOBLminmcjG3qt+JeEXrh5/9x+QSc7Emc6cQ=。前 16 个字节是 IV,它是十六进制编码的 2423c5414ead3812e68a799c8c6deab7。如果此 IV 用于 CryptoJS 代码(s. 注释掉的行),则会产生相同的密文结果。