如何使用CryptoJS在Node.js中成功解密由OpenSSL生成的AES-256加密内容

时间:2019-10-08 00:23:20

标签: node.js encryption openssl aes cryptojs

上下文

我有一个Node.js AWS Lambda函数,它充当自定义授权者并由AWS API Gateway触发,该函数应该从Authorization标头中获取令牌,该标头是AES-256加密的JSON,并且使用CryptoJS和一个秘密密码对其解密。仅供参考,令牌不是JWT。 我已经关注了CryptoJS个文档,但无法正常工作。我已经阅读了数十篇文章和文章,而我却找不到能尝试像我这样的简单方法的人,这真让我感到惊讶。

步骤和代码

1)我有一个名为 token.json 的文件,其中包含一个字符串化的JSON对象:

"{"user_id":1,"name":"user","time":"2019-09-27 13:58:22","env":"dev"}"

2)按照CryptoJS示例,在我正在执行的终端中: openssl enc -aes-256-cbc -in token.json -out encrypted-json-token -pass pass:"password" -e -A -base64

我正在使用-A选项来获得一个单行字符串。 根据{{​​1}}:

  

-A与-[base64 | a]一起用于将base64缓冲区指定为单行

3)我要获取该输出,加密的令牌,并将其作为由AWS API Gateway解析的HTTP请求中openssl enc --help头的值发送,该请求将接收该头并将其传递给我Lambda函数。

4)在Lambda函数中:

Authorization

解密的结果是一个空字符串,因此解析为JSON失败。

最后的笔记

我之所以打电话给const AES = require('crypto-js/aes'); const Utf8 = require('crypto-js/enc-utf8'); module.exports.authenticate = function authenticate(event, context, callback) { ... try { const token = event.authorizationToken; const decryptedToken = AES.decrypt(token, 'password').toString(Utf8); const parsedToken = JSON.parse(decryptedToken); } catch(error){ // log error } ... } ,是因为根据thisthis,解密操作的输出是一个 Word Array对象,我需要将其恢复为原始的字符串形式,该形式应该是字符串化的JSON令牌。 另外,我正在使用无服务器脱机插件在本地模拟API Gateway进行所有测试。

1 个答案:

答案 0 :(得分:1)

TL; DR :使用-K标志传递编码为十六进制的实际AES密钥。

如果您仔细阅读documentation for openssl enc,就会发现-pass-k)和-K标志之间存在差异-第一个实际上是密码,第二个是实际密钥。

如果您使用-pass,则实际上是在传递一个任意字符串密码,该密码通过一个(过时且不安全的)KDF EVP_KDF来馈送。如果您使用-K,则可以将真实的AES密钥作为十六进制字符串传递。

由于EVP_KDF不安全,因此我建议后者。