当未指定任何内容时,CryptoJS如何获得IV

How does CryptoJS get an IV when none is specified?

本文关键字:CryptoJS 何获得 IV 未指定 任何内      更新时间:2023-09-26

当使用CryptoJS.AES.encrypt时,如果没有将第三个参数传递给函数,它如何提出初始化向量?有没有办法把它从加密字符串中取出?

我需要

这个的原因是我需要解密使用 Lua 返回CryptoJS.AES.encrypt的东西,但我只有提供的密钥。

CryptoJS的CryptoJS.<BlockCipher>.encrypt有两种加密模式。

  1. 如果传入的密钥不是字符串,而是 WordArray(CryptoJS 的二进制数据内部表示格式),则密钥将按原样获取。此模式需要除 ECB 之外的所有操作模式的 IV,ECB 不使用 IV,因此您不必指定 IV。如果没有传递 IV,它将默认(通过一些 JavaScript 魔法)填充零的 IV(由 0x00 个字节的完整块组成)。

  2. 如果您传入一个字符串的"密钥",它将假定"密钥"是密码。为了从密码中派生密钥,它使用与OpenSSL兼容的派生函数EVP_BytesToKey。此模式生成一个新的 8 字节随机盐,并将其与密码一起使用以生成密钥和 IV。即使您显式传入 IV,也不会使用它。

     CryptoJS.AES.encrypt(msg, password).toString()
    

    生成一个 Base64 编码的密文,该密文开头包含字符串"Salted__",后跟 8 字节盐和实际密文。您可以在使用前将其显式拆分为:

     var ct = CryptoJS.AES.encrypt(msg, password);
     var saltHex = ct.salt.toString();     // random salt
     var ctHex = ct.ciphertext.toString(); // actual ciphertext
     var ivHex = ct.iv.toString();         // generated IV
    

    如果需要重新创建相同的密钥派生。查看代码和规范。

    密钥应该具有高熵,并且与随机噪声无法区分,这使得它们很难被暴力破解。上述EVP_BytesToKey并不安全,因为 MD5 哈希非常快,这使得攻击者能够暴力破解密码。您要么需要使用很长的密码(20-30个字符),要么使用适当的密钥派生函数,例如CryptoJS提供的PBKDF2。