Javascript CryptoJS和密钥/IV长度

Javascript CryptoJS和密钥/IV长度,javascript,cryptojs,Javascript,Cryptojs,我对AES密钥和IV长度有疑问 首先,例如,如果我正在使用DrugesOpenSSL扩展和OpenSSL\u encrypt()方法,我可以清楚地看到256位AES的密钥应该是32字节,如果它与16字节不同,IV会发出警告。我能理解,一切都很好 然而,在CryptoJS库中,密钥和IV长度令人沮丧。这是一个例子: var text = "test", key = "us5N0PxHAWuIgb0/Qc2sh5OdWBbXGady", iv = "zAvR2NI87bBx74

我对AES密钥和IV长度有疑问

首先,例如,如果我正在使用Druges
OpenSSL
扩展和
OpenSSL\u 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之间有什么区别?

看起来我已经找到了

如果您倾向于在使用CryptoJS时传递自定义
密钥
IV
,请确保(假设
CryptoJS.enc.Base64.parse()
给出十六进制字符串,该字符串用于
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,键的长度为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.

1.你的号码有问题。AES的块大小为128位,这也是IV的预期大小。对于大于或小于16字节的IV,未指定AES。IV尺寸与钥匙尺寸不同。2.22字节不是有效的base64编码字符串。它必须可以被4整除(带有可选的pad字符)。如果是AES-128,则AES的块大小为128。对于AES-256,块大小显然是256位,即32字节,这正是通过22字节Base64字符串的
CryptoJS.enc.Base64.parse()
得到的。根据规范和算法,IV正好是块大小长度,AES-256的长度为32字节。如需更深入的解释,请参阅,如果您提及某个内容,请确保它支持您的声明:sqrt(23)写道:“AES恰好是众多[…]中的一个,具有16字节的恒定块大小”和“初始化向量,通常与密码的块大小匹配”。它不支持您的说法。密钥大小和块大小是不同的。AES-256中的256表示密钥大小。它是针对AES-128的。它说,“初始化向量,通常与密码的块大小匹配“。对于分组密码操作模式,IV通常与密码的块大小一样大。所以,对于256位AES,我看是32字节。