CryptoJS和密钥/ IV长度

Dam*_*nic 6 javascript cryptojs

我对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 });
Run Code Online (Sandbox Code Playgroud)

其中key为32字节,IV为16.CryptoJS需要解析它,并在CryptoJS.enc.Base64.parse()我得到相应的48和24字节后.我希望这些值会被截断为所需的256位AES长度,并且进一步扩展到n个字节将是无关紧要的,因此产生的密文将是相同的.

但实际上并没有发生这种情况.当我传递给CryptoJS.AES.encrypt()更大的密钥甚至 IV时,它产生不同的输出.所以我的问题是,为什么?在这种情况下,CryptoJS 库和OpenSSL有什么区别?

Dam*_*nic 13

看起来我已经知道了.

如果您倾向于传递自定义keyIV使用CryptoJS,请确保(假设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"
Run Code Online (Sandbox Code Playgroud)

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
Run Code Online (Sandbox Code Playgroud)

另外,从我所看到的,只有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.
Run Code Online (Sandbox Code Playgroud)

  • 1. 你的号码有问题。AES 的块大小为 128 位,这也是 IV 的预期大小。AES 未指定用于大于或小于 16 字节的 IV。IV 大小与密钥大小不同。2. 22 字节不是有效的 base64 编码字符串。它必须能被 4 整除(带有可选的填充字符)。 (2认同)