最新消息: 电脑我帮您提供丰富的电脑知识,编程学习,软件下载,win7系统下载。

如何使用CryptoJS成功解密由Node.js中的OpenSSL生成的AES

IT培训 admin 3浏览 0评论

如何使用CryptoJS成功解密由Node.js中的OpenSSL生成的AES

上下文

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

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

3)我要获取该输出,加密的令牌,并将其作为由AWS API Gateway解析的HTTP请求中Authorization标头的值发送,该请求将获得该标头并将其传递给我的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),因为根据this和this,解密操作的输出是字数组对象,我需要将其恢复为原始字符串形式,即应该是字符串化的JSON令牌。另外,我正在使用无服务器脱机插件在本地模拟API网关来测试所有这一切。

回答如下:

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

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

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

由于-K不安全,所以我建议后者。

如何使用CryptoJS成功解密由Node.js中的OpenSSL生成的AES

上下文

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

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

3)我要获取该输出,加密的令牌,并将其作为由AWS API Gateway解析的HTTP请求中Authorization标头的值发送,该请求将获得该标头并将其传递给我的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),因为根据this和this,解密操作的输出是字数组对象,我需要将其恢复为原始字符串形式,即应该是字符串化的JSON令牌。另外,我正在使用无服务器脱机插件在本地模拟API网关来测试所有这一切。

回答如下:

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

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

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

由于-K不安全,所以我建议后者。

发布评论

评论列表 (0)

  1. 暂无评论