我需要解密使用AES加密的传入请求,我尝试使用共享示例,但无法找到正确的参数集。
我用next
const cryptkey = '1234567890123456';
const cleardata = "abcdefghigklmnopqrstuvwxyz0123456789";
const crypted = "8Z3dZzqn05FmiuBLowExK0CAbs4TY2GorC2dDPVlsn/tP+VuJGePqIMv1uSaVErr";
var decrypt = CryptoJS.AES.decrypt(crypted, cryptkey, {
iv: CryptoJS.enc.Hex.parse('0000000000000000'),
mode: CryptoJS.mode.CBC,
padding: CryptoJS.pad.Pkcs7
});
var ddd = decrypt.toString(CryptoJS.enc.Utf8);
console.log(ddd);每次我得到空字符串。我在哪里失败?
-更新
带有应用注释的新版本,仍然不能工作。
const cryptkey = CryptoJS.enc.Utf8.parse('1234567890123456');
const crypted = CryptoJS.enc.Base64.parse("8Z3dZzqn05FmiuBLowExK0CAbs4TY2GorC2dDPVlsn/tP+VuJGePqIMv1uSaVErr");
var decrypt = CryptoJS.AES.decrypt(crypted, cryptkey, {
iv: CryptoJS.enc.Hex.parse('00000000000000000000000000000000'),
mode: CryptoJS.mode.CBC,
padding: CryptoJS.pad.Pkcs7
});发布于 2017-03-24 06:29:53
您必须首先解析UTF-8键:
const cryptkey = CryptoJS.enc.Utf8.parse('1234567890123456');如果您不这样做,CryptoJS将假设它是一个密码,并从中派生出实际的密钥。
正如马滕所指出的..。
密文还必须从Base64解码:
const crypted = CryptoJS.enc.Base64.parse("8Z3dZzqn05FmiuBLowExK0CAbs4TY2GorC2dDPVlsn/tP+VuJGePqIMv1uSaVErr");注意,解密器需要一个CipherParams对象,您可以通过将{ciphertext: crypted}传递给decrypt函数来模拟这个对象。或者,您可以依赖CryptoJS从Base64中解码密文,您可以按原样传递该字符串。
对于AES-CBC来说,IV必须有16个字节长,如果编码为十六进制,这些字符是32个字符:
CryptoJS.enc.Hex.parse('00000000000000000000000000000000')示例
const cryptkey = CryptoJS.enc.Utf8.parse('1234567890123456');
const crypted = CryptoJS.enc.Base64.parse("8Z3dZzqn05FmiuBLowExK0CAbs4TY2GorC2dDPVlsn/tP+VuJGePqIMv1uSaVErr");
var decrypt = CryptoJS.AES.decrypt({ciphertext: crypted}, cryptkey, {
iv: CryptoJS.enc.Hex.parse('00000000000000000000000000000000'),
mode: CryptoJS.mode.CBC,
padding: CryptoJS.pad.Pkcs7
});
console.log(decrypt.toString(CryptoJS.enc.Utf8));<script src="https://cdn.rawgit.com/CryptoStore/crypto-js/3.1.2/build/rollups/aes.js"></script>
正如Matt正确指出的,如果密文被编码为Base64,Base64可以为您执行密文解码:
const cryptkey = CryptoJS.enc.Utf8.parse('1234567890123456');
const crypted = "8Z3dZzqn05FmiuBLowExK0CAbs4TY2GorC2dDPVlsn/tP+VuJGePqIMv1uSaVErr";
var decrypt = CryptoJS.AES.decrypt(crypted, cryptkey, {
iv: CryptoJS.enc.Hex.parse('00000000000000000000000000000000'),
mode: CryptoJS.mode.CBC,
padding: CryptoJS.pad.Pkcs7
});
console.log(decrypt.toString(CryptoJS.enc.Utf8));<script src="https://cdn.rawgit.com/CryptoStore/crypto-js/3.1.2/build/rollups/aes.js"></script>
安全考虑因素:
IV必须是不可预测的(读:随机)。不要使用静态IV,因为这使得密码具有确定性,因此在语义上不安全。观察密文的攻击者可以确定之前何时发送相同的消息前缀。IV不是秘密的,所以你可以把它和密文一起发送。通常,它只是简单地先于密文,并在解密前被分割掉。
应该从所有可能的字节中随机选择一个键,因为包含ASCII字符的键比由所有可用字节组成的键要容易得多。
最好对密文进行身份验证,这样就不可能发生像padding oracle attack这样的攻击。这可以通过GCM或EAX等经过身份验证的模式完成,也可以使用encrypt-then-MAC方案来完成。
如果您只使用对称加密,则服务器和客户端需要完全相同的密钥。如果将加密密钥从服务器发送到客户端,或者反过来,则需要对对称加密密钥进行加密。最简单的方法是使用TLS。如果使用TLS,那么数据和密钥都是加密的,所以不需要自己加密。这不提供任何安全,只是一点点混淆。您应该阅读:https://www.nccgroup.trust/us/about-us/newsroom-and-events/blog/2011/august/javascript-cryptography-considered-harmful/
发布于 2017-03-24 01:13:23
您忘记了在crypted中以64为基础来解码密文(我想您必须使用atob()来实现这一点)。您的IV也太小了,十六进制每字节取两个十六进制数字。
发布于 2021-08-04 04:37:45
这是我的工作,使用enc而不仅仅是UTF8。
const { AES, enc } = require('crypto-js')
const { decrypt, encrypt } = AES
const message = "Hi my friend"
const messageEncrypt = "oPVu8Dd8ERPIAWr+7rQzIQ=="
const key= "key123456"
const aesDecrypt = decrypt(messageEncrypt,key).toString(enc.Utf8)
console.log(aesDecrypt) // Hi my friendhttps://stackoverflow.com/questions/42989586
复制相似问题