CryptoJS 和 key/IV 长度
CryptoJS and key/IV length
我对 AES 密钥和 IV 长度有疑问。
首先,例如,如果我使用 drugs OpenSSL
扩展和 openssl_encrypt()
方法,我可以清楚地看到该键256 位 AES 应该是 32 字节,如果它不同于 16 字节,IV 会抛出警告。我能理解,一切都很好。
然而,在 CryptoJS
库中,密钥和 IV 长度令人沮丧。这是一些例子:
var text = "test",
key = "us5N0PxHAWuIgb0/Qc2sh5OdWBbXGady",
iv = "zAvR2NI87bBx746n";
key = CryptoJS.enc.Base64.parse(key);
iv = CryptoJS.enc.Base64.parse(iv);
crypted = CryptoJS.AES.encrypt(text, key, { iv: iv });
其中 key 是 32 字节,IV 是 16。 CryptoJS 需要解析它,在 CryptoJS.enc.Base64.parse()
之后我相应地得到 48 和 24 字节。我希望这些值将被截断为所需的 256 位 AES 长度,进一步扩展到 n 字节将是无关紧要的,因此生成的密文将是相同的。
但这实际上并没有发生。当我传递给 CryptoJS.AES.encrypt() 更大尺寸的键和 even IV 时,它会产生不同的输出。所以我的问题是,为什么?在这种情况下,CryptoJS 库和 OpenSSL 有什么区别?
看来我明白了。
如果您在使用 CryptoJS 时倾向于通过自定义 key
和 IV
,请确保(假设 CryptoJS.enc.Base64.parse()
给出 HEX 字符串,用于CryptoJS.AES.encrypt()
) keys length are matching the block size.
以这个例子为例,使用Base64密钥和iv(长度=22),CryptoJS加密为AES -256:
var message = "some_secret_message";
var key = "6Le0DgMTAAAAANokdEEial"; //length=22
var iv = "mHGFxENnZLbienLyANoi.e"; //length=22
key = CryptoJS.enc.Base64.parse(key);
//key is now e8b7b40e031300000000da247441226a, length=32
iv = CryptoJS.enc.Base64.parse(iv);
//iv is now 987185c4436764b6e27a72f2fffffffd, length=32
var cipherData = CryptoJS.AES.encrypt(message, key, { iv: iv });
var data = CryptoJS.AES.decrypt(cipherData, key, { iv: iv });
//data contains "some_secret_message"
对于 AES-256,key
的长度为 32 个字节。 (如果你想获得 AES-128,则为 16 个字节。如果更多,CryptoJS 将切换到更高的密钥长度)。在其他情况下,解密时您将收到一条空消息。示例:
var message = "some_secret_message";
var key = "6Le0DgMTAAAAANokdEEial1"; //length=23
var iv = "mHGFxENnZLbienLyANoi.e"; //length=22
key = CryptoJS.enc.Base64.parse(key); // length = 17 bytes
//key is now e8b7b40e031300000000da247441226a5d, length=34 (hex encoded)
iv = CryptoJS.enc.Base64.parse(iv); // length = 16 bytes
//iv is now 987185c4436764b6e27a72f2fffffffd, length=32 (hex encoded)
var cipherData = CryptoJS.AES.encrypt(message, key, { iv: iv });
var data = CryptoJS.AES.decrypt(cipherData, key, { iv: iv });
//data contains "" - an empty string
此外,据我所知,只有 x % 8 == 0
字节的此类用例给出了有效结果。
IV
的长度应该是 22 字节(当 Base64 编码时),而当使用 CryptoJS.enc.Base64.parse()
转换时你将得到 16 字节(32 十六进制编码),这是 [=33= 的最大值]AES-256 块大小。除此以外的所有内容都会被截断。
var message = "some_secret_message";
var key = "6Le0DgMTAAAAANokdEEial"; //length=22
var iv = "mHGFxENnZLbienLyANoi.e"; //length=22
key = CryptoJS.enc.Base64.parse(key); // length=16 bytes
//key is now e8b7b40e031300000000da247441226a5d, length=32 (hex encoded)
iv = CryptoJS.enc.Base64.parse(iv); // length=16 bytes
//iv is now 987185c4436764b6e27a72f2fffffffd, length=32 (hex encoded)
var cipherData = CryptoJS.AES.encrypt(message, key, { iv: iv });
var key = "6Le0DgMTAAAAANokdEEial"; //length=22
var iv = "mHGFxENnZLbienLyANoi.e123"; //length=25
key = CryptoJS.enc.Base64.parse(key); // length = 16 bytes
//key is now e8b7b40e031300000000da247441226a5d, length=32 (hex encoded)
iv = CryptoJS.enc.Base64.parse(iv); // length = 18 bytes
//iv is now 987185c4436764b6e27a72f2fffffffded76, length=36 (hex encoded)
var data = CryptoJS.AES.decrypt(cipherData, key, { iv: iv }); //data contains "some_secret_message", so additional "123" in IV is irrelevant.
我对 AES 密钥和 IV 长度有疑问。
首先,例如,如果我使用 drugs OpenSSL
扩展和 openssl_encrypt()
方法,我可以清楚地看到该键256 位 AES 应该是 32 字节,如果它不同于 16 字节,IV 会抛出警告。我能理解,一切都很好。
然而,在 CryptoJS
库中,密钥和 IV 长度令人沮丧。这是一些例子:
var text = "test",
key = "us5N0PxHAWuIgb0/Qc2sh5OdWBbXGady",
iv = "zAvR2NI87bBx746n";
key = CryptoJS.enc.Base64.parse(key);
iv = CryptoJS.enc.Base64.parse(iv);
crypted = CryptoJS.AES.encrypt(text, key, { iv: iv });
其中 key 是 32 字节,IV 是 16。 CryptoJS 需要解析它,在 CryptoJS.enc.Base64.parse()
之后我相应地得到 48 和 24 字节。我希望这些值将被截断为所需的 256 位 AES 长度,进一步扩展到 n 字节将是无关紧要的,因此生成的密文将是相同的。
但这实际上并没有发生。当我传递给 CryptoJS.AES.encrypt() 更大尺寸的键和 even IV 时,它会产生不同的输出。所以我的问题是,为什么?在这种情况下,CryptoJS 库和 OpenSSL 有什么区别?
看来我明白了。
如果您在使用 CryptoJS 时倾向于通过自定义 key
和 IV
,请确保(假设 CryptoJS.enc.Base64.parse()
给出 HEX 字符串,用于CryptoJS.AES.encrypt()
) keys length are matching the block size.
以这个例子为例,使用Base64密钥和iv(长度=22),CryptoJS加密为AES -256:
var message = "some_secret_message";
var key = "6Le0DgMTAAAAANokdEEial"; //length=22
var iv = "mHGFxENnZLbienLyANoi.e"; //length=22
key = CryptoJS.enc.Base64.parse(key);
//key is now e8b7b40e031300000000da247441226a, length=32
iv = CryptoJS.enc.Base64.parse(iv);
//iv is now 987185c4436764b6e27a72f2fffffffd, length=32
var cipherData = CryptoJS.AES.encrypt(message, key, { iv: iv });
var data = CryptoJS.AES.decrypt(cipherData, key, { iv: iv });
//data contains "some_secret_message"
对于 AES-256,key
的长度为 32 个字节。 (如果你想获得 AES-128,则为 16 个字节。如果更多,CryptoJS 将切换到更高的密钥长度)。在其他情况下,解密时您将收到一条空消息。示例:
var message = "some_secret_message";
var key = "6Le0DgMTAAAAANokdEEial1"; //length=23
var iv = "mHGFxENnZLbienLyANoi.e"; //length=22
key = CryptoJS.enc.Base64.parse(key); // length = 17 bytes
//key is now e8b7b40e031300000000da247441226a5d, length=34 (hex encoded)
iv = CryptoJS.enc.Base64.parse(iv); // length = 16 bytes
//iv is now 987185c4436764b6e27a72f2fffffffd, length=32 (hex encoded)
var cipherData = CryptoJS.AES.encrypt(message, key, { iv: iv });
var data = CryptoJS.AES.decrypt(cipherData, key, { iv: iv });
//data contains "" - an empty string
此外,据我所知,只有 x % 8 == 0
字节的此类用例给出了有效结果。
IV
的长度应该是 22 字节(当 Base64 编码时),而当使用 CryptoJS.enc.Base64.parse()
转换时你将得到 16 字节(32 十六进制编码),这是 [=33= 的最大值]AES-256 块大小。除此以外的所有内容都会被截断。
var message = "some_secret_message";
var key = "6Le0DgMTAAAAANokdEEial"; //length=22
var iv = "mHGFxENnZLbienLyANoi.e"; //length=22
key = CryptoJS.enc.Base64.parse(key); // length=16 bytes
//key is now e8b7b40e031300000000da247441226a5d, length=32 (hex encoded)
iv = CryptoJS.enc.Base64.parse(iv); // length=16 bytes
//iv is now 987185c4436764b6e27a72f2fffffffd, length=32 (hex encoded)
var cipherData = CryptoJS.AES.encrypt(message, key, { iv: iv });
var key = "6Le0DgMTAAAAANokdEEial"; //length=22
var iv = "mHGFxENnZLbienLyANoi.e123"; //length=25
key = CryptoJS.enc.Base64.parse(key); // length = 16 bytes
//key is now e8b7b40e031300000000da247441226a5d, length=32 (hex encoded)
iv = CryptoJS.enc.Base64.parse(iv); // length = 18 bytes
//iv is now 987185c4436764b6e27a72f2fffffffded76, length=36 (hex encoded)
var data = CryptoJS.AES.decrypt(cipherData, key, { iv: iv }); //data contains "some_secret_message", so additional "123" in IV is irrelevant.