使用CryptoJS解密openssl AES

提供

我正在尝试使用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

我缺少明显的东西吗?

dave_thompson_085

还不是一个肯定的答案,但是太多评论了:

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] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章