我对AES密钥和IV长度有疑问。
首先,例如,如果我使用药物 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()更大的密钥和甚至 IV时,它会产生不同的输出。所以我的问题是,为什么?在这种情况下, CryptoJS 库与 OpenSSL 之间有什么区别?
答案 0 :(得分:11)
看起来我已经得到了它。
如果您倾向于使用 CryptoJS 传递自定义key
和IV
,请确保(假设CryptoJS.enc.Base64.parse()
提供 HEX 字符串,用于CryptoJS.AES.encrypt()
)。
以此示例为例, 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个十六进制编码),这是 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.