【问题标题】:How to successfully decrypt AES-256 encrypted content generated with OpenSSL in Node.js using CryptoJS如何使用 CryptoJS 在 Node.js 中成功解密使用 OpenSSL 生成的 AES-256 加密内容
【发布时间】:2019-10-08 00:23:20
【问题描述】:

上下文

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

步骤和代码

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 选项来获取单行字符串。 根据openssl enc --help

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

3) 我正在获取该输出,加密令牌,并将其作为 Authorization 标头的值发送到由 AWS API Gateway 解析的 HTTP 请求中,AWS API Gateway 获取该标头并将其传递给我的 Lambda 函数.

4) 在 Lambda 函数中:

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
  }
...
}

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

最后的笔记

我打电话给.toString(Utf8),因为根据thisthis,解密操作的输出是一个字数组对象,我需要把它变回原来的样子字符串形式,应该是字符串化的 JSON 令牌。 另外,我正在使用无服务器离线插件在本地模拟 API 网关来测试所有这些。

【问题讨论】:

    标签: node.js encryption openssl aes cryptojs


    【解决方案1】:

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

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

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

    由于EVP_KDF 不安全,我推荐后者。

    【讨论】:

    • 感谢您的回答。它为我指明了正确的方向。现在的问题是,OpenSSL 不允许 just 传递 -K 选项和十六进制编码的密钥;您还需要传递一个十六进制编码的 IV。据我所知,IV 实际上是最终密文的一部分,因此不需要将其与密钥一起存储,但如果我在使用 openssl 加密某些内容然后在 Node 中解密时未指定 IV .js,然后有一些未正确解密的前置密文。那么,在加密某些东西以供以后解密时,我应该还是不应该存储 IV?
    • IV 不是秘密 - 与密文一起存储并通过不安全的通道是完全安全的。唯一的要求是您为每个加密操作使用一个新的 IV,并且它是不可预测的。标准方法是随机生成一个,将其用于加密,然后将其添加到密文中以供解密时使用。
    猜你喜欢
    • 1970-01-01
    • 2017-02-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-06-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多