我正在尝试使用CryptoJS 3.1.5解密使用openssl加密的文件。
如果我使用CryptoJS进行加密和解密,一切都会正常运行,外壳中的OpenSSL也是如此,但是当我尝试将CryptoJS与OpenSSL混合使用时,一切都会出错。
使用以下命令创建文件:
openssl enc -aes-256-cbc -in file.txt -out file.enc -k password
我尝试像这样解密:
fs.readFile('file.enc', function(err, data) {
var decrypted = CryptoJS.AES.decrypt(
data.toString(),
"password",
{ mode : CryptoJS.mode.CBC }
);
console.log(decrypted.toString(CryptoJS.enc.Utf8));
});
// Give me this err: Uncaught Error: Malformed UTF-8 data
另外,我这样做:
fs.readFile('file.txt', function(err, data) {
var encrypted = CryptoJS.AES.encrypt(
data.toString(),
"password",
{ mode : CryptoJS.mode.CBC });
fs.writeFile('file.enc', encrypted);
});
然后在Shell中:
openssl enc -d -aes-256-cbc -in file.enc -out file2.txt -k password
// Give me this err: bad magic number
我缺少明显的东西吗?
还不是一个肯定的答案,但是太多评论了:
openssl enc
默认情况下,命令行使用带有盐的基于密码的加密(PBE),这意味着实际的加密密钥以及适用于CBC的IV(如果适用)是通过基于密码的密钥派生函数根据给定的密码和随机盐值计算得出的,使得对手更难尝试猜测密码的攻击。我不知道您的JS模块(或根本没有JS),但是您链接的网页上列出了各种低级原语,表明它不能自动执行PBE。像“密码”这样的文本字符串(可能)适用于PBE,但不适合直接AES加密,因为密钥必须恰好是128、192或256位,并且应该是随机二进制数据。
如果要使用openssl的半标准PBE,请在JS端进行匹配;该项目evpkey
听起来可能有用,因为EVP
涉及了openssl模块,而且我不知道其他(PB)KDF方案会被称为EVP。如果不是,则enc
默认PBE只是密码中与salt关联的MD5,并根据需要迭代多次反馈,在这种情况下为3。请参阅https://superuser.com/questions/455463/openssl-hash-function-for-generating-aes-key中的(主要是)perl中的示例。OpenSSL在文件前加上8个ASCII字符“ Salted__”和8字节的salt,因此您需要在解密之前将其删除(并使用salt),或在加密后添加它们。
如果要进行原始加密,请选择一个更合适的密钥(无论在哪一侧),以及一个唯一且不可预测的IV,除非您始终使用新密钥,在这种情况下可以使用固定的IV,而在openssl一侧使用-K
(请注意大写)并-iv
以十六进制指定这些值。请参阅任何安装了openssl的Unix系统上的手册页,或参阅https://www.openssl.org/docs/manmaster/apps/enc.html。
在这两种情况下,加号都enc
默认为“ PKCS#5”(实际上是PKCS#7)填充。我不知道您的JS模块是否可以。如果不是,则应指定它。除非可以保证您的纯文本始终是16字节的精确倍数(在诸如UTF8之类的任何编码之后);那么您可以在JS端指定(或默认)没有填充,并-nopad
在openssl端指定。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句