网站搜索

javascript - 类型错误:无法读取未定义的属性 '0' CryptoJS


我在我的 Angular 应用中使用 CryptoJS 实现 AES 加密,但当我尝试在 IV 中发送空的 16 字节数组时,始终收到 TypeError: Cannot read property '0' of undefined 错误

这是我的 TypeScript 代码:

aesEncrypt(keys: string, value: string) { // encrypt api request parameter with aes secretkey

    var key = CryptoJS.enc.Utf8.parse(keys);
    //var iv = CryptoJS.enc.Utf8.parse(keys);
    var iv = new Uint16Array(16);
    var encrypted = CryptoJS.AES.encrypt(JSON.stringify(value), key,
        {
            //keySize: 256,
            keySize: 128,
            iv: iv,
            mode: CryptoJS.mode.CBC,
            padding: CryptoJS.pad.Pkcs7,
        });

    return encrypted.toString();
}

但是当我在 IV 中发送空的 16 字节数组时,同样的东西在 .NET、Android、iOS 中工作正常

.NET 代码:

private static AesCryptoServiceProvider AesCryptoServiceProvider(string key)
{
    AesCryptoServiceProvider aes = new AesCryptoServiceProvider();
    aes.KeySize = 128;
    aes.BlockSize = 128;
    aes.Mode = CipherMode.CBC;
    aes.Padding = PaddingMode.PKCS7;
    aes.Key = Encoding.UTF8.GetBytes(key);
    //aes.IV = Encoding.UTF8.GetBytes(key);
    aes.IV = new byte[16];
    return aes;
}

安卓代码:

public static String encryptURLEncoding(byte[] key, String encryption) throws GeneralSecurityException 
{
    if (key.length != 16) 
    {
        throw new IllegalArgumentException("Invalid key size.");
    }

    // Setup AES tool.

    SecretKeySpec skeySpec = new SecretKeySpec(key, "AES");
    Cipher cipher = Cipher.getInstance("AES/CBC/PKCS7Padding");
    cipher.init(Cipher.ENCRYPT_MODE, skeySpec, new IvParameterSpec(new byte[16]));
    byte[] dstBuff = cipher.doFinal(encryption.getBytes());
    String encryptedStringData = android.util.Base64.encodeToString(dstBuff, android.util.Base64.DEFAULT);
    return encryptedStringData;
}

我想通过提供一个空的16字节数组来实现AES加密解密,因为这个应用程序与我其他在安卓和iOS平台上的应用程序互联,这些应用程序使用相同的加密设置,但我在Angular应用中遇到了错误,我该如何解决这个问题?

答案#1

在 JavaScript 代码中,IV 必须作为 WordArray 传递。由于在 C# 代码中使用了 0-IV,因此在 JavaScript 代码中也必须这样做。相应的 WordArray 可以是例如。

var iv = CryptoJS.enc.Hex.parse("00000000000000000000000000000000");

请注意,使用十六进制编码器是为了使16字节的0-IV对应于32个0值。

还要注意,通常情况下 0-IV 仅应用于测试目的。在实际操作中,出于安全原因,每次加密都必须生成一个随机 IV。此外,密钥/IV 对只能使用一次。

此外,CryptoJS 不识别参数 keySize 并会忽略它。所使用的 AES 变体是由密钥大小决定的,例如,对于 32 字节的密钥,这里将应用 AES-256。

答案#2

对于在 TypeScript 中加密字符串时遇到类似错误的人,你只需通过这种方式导入该包

import * as Crypto from 'crypto-js';