【问题标题】:TypeError: Cannot read property '0' of undefined CryptoJSTypeError:无法读取未定义 CryptoJS 的属性“0”
【发布时间】:2020-06-23 06:18:11
【问题描述】:

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

这是我的打字稿代码:

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 加密解密,因为这个应用程序与我在 android、ios 平台上的其他应用程序具有相同的加密设置,但我的 angular 应用程序出现错误,我该如何解决这个问题?

【问题讨论】:

  • 在 JavaScript 代码中,IV 必须作为 WordArray 传递。在 C# 代码中,使用 0-IV(byte[] 和 16 个 0-值)。对应的WordArray 将是例如var iv = CryptoJS.enc.Hex.parse("00000000000000000000000000000000");
  • @Topaco 我需要在 WordArray 中传递 16 个 0 以获得 16 字节数组?
  • 由于使用了十六进制编码器,IV被编码为十六进制字符串,即32个零表示16个零字节。
  • 此外 CryptoJS 不知道参数keySize。使用的 AES 变体由密钥大小决定,例如对于 32 字节密钥,使用 AES-256。
  • @Topaco 非常感谢您提供的信息。错误消失了,现在它在 angular 和 .net api 中工作正常,现在我需要与 android 和 ios 上的其他应用程序交叉验证

标签: javascript arrays typescript aes cryptojs


【解决方案1】:

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

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

请注意,使用Hex encoder 是为了使16 个字节的0-IV 对应于32 个0-值。

另外请注意,0-IV 通常只应用于测试目的。实际上,出于安全原因,必须为每次加密生成一个随机 IV。此外,密钥/IV 对只能使用一次。

此外 CryptoJS 不知道参数keySize 并忽略它。使用的 AES 变体由密钥大小决定,例如对于 32 字节密钥,应用 AES-256,here

【讨论】:

    【解决方案2】:

    我遇到了同样的问题。 包括 iv 选项解决了它。

    var iv = CryptoJS.enc.Hex.parse("101112131415161718191a1b1c1d1e1f"); var ciphertext = CryptoJS.AES.encrypt("msg", CryptoJS.enc.Hex.parse("000102030405060708090a0b0c0d0e0f"),{ iv: iv, mode: CryptoJS.mode.CTR, padding: CryptoJS.pad.AnsiX923 });

    【讨论】:

      【解决方案3】:

      对于那些在 typescript 加密字符串时遇到类似错误的人,您只需要以这种方式导入包

      import * as Crypto from 'crypto-js';
      

      【讨论】:

        猜你喜欢
        • 2020-11-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2023-02-26
        • 2019-08-04
        • 2015-06-08
        • 1970-01-01
        相关资源
        最近更新 更多