【问题标题】:NodeJS | Crypto Encryption is not producing correct results节点JS |加密加密没有产生正确的结果
【发布时间】:2017-09-19 19:54:14
【问题描述】:

我有一个棘手的问题要解决。不知道如何正确解释,但会尽力而为。所以这就是我想要做的事情:我正在尝试使用第 3 方 API,它希望我加密一个值并提交它。我使用以下代码块通过 C# 代码成功实现了它:

public string Encrypt(byte[] dataToEncrypt, byte[] keyBytes)
       {
           AesManaged tdes = new AesManaged();

           tdes.KeySize = 256;
           tdes.BlockSize = 128;
           tdes.Key = keyBytes;
           tdes.Mode = CipherMode.ECB;
           tdes.Padding = PaddingMode.PKCS7;

           ICryptoTransform crypt = tdes.CreateEncryptor();
           byte[] cipher = crypt.TransformFinalBlock(dataToEncrypt, 0, dataToEncrypt.Length);
           tdes.Clear();
           return Convert.ToBase64String(cipher, 0, cipher.Length);

       }

现在,我正在尝试在 Node.js 中实现相同的目标。我写了以下函数。

encrypt(buffer){
            var buffbytes = new Buffer('my app key goes here to be used as password','utf8'); //converts the app key into buffer stream
            return this.encrypt_key(new Buffer(buffer,'utf8'), buffbytes);
        },

        encrypt_key(buffer, keybytes){
            var cipher = crypto.createCipher('aes-128-ecb',keybytes);
            var crypted = cipher.update(buffer,'utf8','base64');
            crypted = crypted+ cipher.final('base64');
            return crypted;
        },

此加密代码工作正常。它可以很好地加密它,但它不会像 c# 代码那样加密它。当我从 C# 代码中获取加密文本,并将加密结果注入 API 调用时,它可以正常通过,但是当我将加密结果用于 API 调用时,它没有提到我的密钥格式不正确。

我想知道这些代码块是否相同。我认为它是相同的,因为使用 128 位 AES、ECB 密码和 Crypto Node 模块的默认填充的代码都是 PKCS5,这与 PKCS7 用于 128 位加密相同。请帮忙!

编辑:2017 年 9 月 19 日

根据@smarx 解决方案修复:

        encrypt(buffer){
            var buffbytes = new Buffer(helper.Constants.AppKey,'utf8'); //converts the app key into buffer stream
            return this.encrypt_key(new Buffer(buffer,'utf8'), helper.Constants.AppKey);
        },

        encrypt_key(buffer, key){
            var cipher = crypto.createCipheriv('aes-256-ecb',key,new Buffer(0));
            var crypted = cipher.update(buffer,'utf8','base64');
            crypted = crypted+ cipher.final('base64');
            console.log('printed: ', crypted);
            return crypted;
        },

【问题讨论】:

  • 仅供参考,我的密码密钥也是 32 字节(256 位)。所以我不确定我错过了什么。

标签: node.js encryption cryptography


【解决方案1】:

在您的 Node.js 代码中,您使用了错误的密码算法。使用aes-256-ecb,因为您使用的是 256 位密钥。另外,请务必使用createCipheriv,因为createCipher 需要一个密码it derives an encryption key 来自该密码。

单行修复:

const cipher = crypto.createCipheriv('aes-256-ecb', key, new Buffer(0));

以下两个程序产生相同的输出 (Q9VZ73VKhW8ZvdcBzm05mw==)。

C#:

var key = System.Text.Encoding.UTF8.GetBytes("abcdefghijklmnopqrstuvwxyz123456");
var data = System.Text.Encoding.UTF8.GetBytes("Hello, World!");

var aes = new AesManaged {
    Key = key,
    Mode = CipherMode.ECB,
};

Console.WriteLine(Convert.ToBase64String(
    aes.CreateEncryptor().TransformFinalBlock(data, 0, data.Length)));

Node.js:

const crypto = require('crypto');

const key = 'abcdefghijklmnopqrstuvwxyz123456';
const data = 'Hello, World!';

const cipher = crypto.createCipheriv('aes-256-ecb', key, new Buffer(0));
console.log(cipher.update(data, 'utf-8', 'base64') + cipher.final('base64'));

【讨论】:

  • 谢谢....本质是使用cipheriv和算法。我基本上尝试了所有可能的算法以及所有密码选项,如 ecb 等……但它没有用,因为我没有使用密码向量。仍然不确定两者之间有什么区别,但仍然非常感谢您的帮助。
  • 是的,createCipher 不直接接受密钥;它接受一个密码,然后从中派生一个密钥。得知这一点我也很惊讶。
  • 快速提问,您是如何发现 createCipher 不接受密钥的。对我来说,它运行得很好,从未产生任何错误。可能是我在这里缺乏常识:)
  • 谢谢...我可能会阅读该文档 100 次...就像我说的那样,我可能缺乏常识:D
猜你喜欢
  • 1970-01-01
  • 2019-09-09
  • 1970-01-01
  • 1970-01-01
  • 2020-05-13
  • 2018-02-26
  • 1970-01-01
  • 1970-01-01
  • 2015-06-23
相关资源
最近更新 更多