首先,例如,如果我使用药物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有什么区别?
解决方法
如果您倾向于使用CryptoJS传递自定义键和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,{ iv: iv }); var data = CryptoJS.AES.decrypt(cipherData,{ 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,{ 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,{ 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,{ iv: iv }); //data contains "some_secret_message",so additional "123" in IV is irrelevant.