【问题标题】:Symmetric encryption with NodeJS使用 NodeJS 进行对称加密
【发布时间】:2023-03-08 05:13:01
【问题描述】:

我很困惑为什么这不起作用,我收到Error: error:06065064:digital envelope routines:EVP_DecryptFinal_ex:bad decrypt

var crypto = require('crypto');
var key = "ciw7p02f70000ysjon7gztjn7";
var pt = "72721827b4b4ee493ac09c635827c15ce014c3c3";

var encrypt = crypto.createCipher('aes256', key);
encrypt.update(pt, 'utf8', 'hex');
var encrypted = encrypt.final('hex')

var decrypt = crypto.createDecipher('aes256', key);
decrypt.update(encrypted, 'hex', 'utf8')
decrypt.final()

您可以使用 RunKit 看到它的动作 ...https://runkit.com/fredyc/bidirectional-encryption-with-nodejs

【问题讨论】:

  • 可能是专门为这个问题创建的密钥值,因为它的长度(25 字节)太短不能作为 AES-256 密钥接受,它必须是 32字节长。对于使用 24 字节密钥的 AES-192 来说,它也有 1 个字节太长。

标签: node.js encryption


【解决方案1】:

通过https://github.com/nodejs/node-v0.x-archive/issues/6386解决

// https://github.com/nodejs/node-v0.x-archive/issues/6386#issuecomment-31817919
// with createCipher / createDecipher (both deprecated) replaced with
// createCipheriv / createDecipheriv and a generated IV passed along.
var assert = require('assert');
var crypto = require('crypto');

var algorithm = 'aes256';
var inputEncoding = 'utf8';
var outputEncoding = 'hex';
var ivlength = 16  // AES blocksize

var key = Buffer.from('ciw7p02f70000ysjon7gztjn7c2x7GfJ', 'latin1'); // key must be 32 bytes for aes256
var iv = crypto.randomBytes(ivlength);

var text = '72721827b4b4ee493ac09c635827c15ce014c3c3';

console.log('Ciphering "%s" with key "%s" using %s', text, key, algorithm);

var cipher = crypto.createCipheriv(algorithm, key, iv);
var ciphered = cipher.update(text, inputEncoding, outputEncoding);
ciphered += cipher.final(outputEncoding);
var ciphertext = iv.toString(outputEncoding) + ':' + ciphered

console.log('Result in %s is "%s"', outputEncoding, ciphertext);

var components = ciphertext.split(':');
var iv_from_ciphertext = Buffer.from(components.shift(), outputEncoding);
var decipher = crypto.createDecipheriv(algorithm, key, iv_from_ciphertext);
var deciphered = decipher.update(components.join(':'), outputEncoding, inputEncoding);
deciphered += decipher.final(inputEncoding);

console.log(deciphered);
assert.equal(deciphered, text, 'Deciphered text does not match!');

使用错误在这里:

// yours (incorrect)
var encrypt = crypto.createCipher('aes256', key);
encrypt.update(pt, 'utf8', 'hex');
var encrypted = encrypt.final('hex')

// correct
var encrypt = crypto.createCipher('aes256', key);
var encrypted = encrypt.update(pt, 'utf8', 'hex');
encrypted += encrypt.final('hex')



// yours (incorrect)
var decrypt = crypto.createDecipher('aes256', key);
decrypt.update(encrypted, 'hex', 'utf8')
decrypt.final()

// correct
var decrypt = crypto.createDecipher('aes256', key);
var decrypted = decrypt.update(encrypted, 'hex', 'utf8')
decrypted += decrypt.final()

但由于 cipher.createCipher()cipher.createDecipher() 现在已弃用且不安全,因此上述解决方案改用 cipher.createCipheriv()cipher.createDecipheriv()

如果您对在消息开头共享前 16 个字节(或 16 个字节的倍数)的多个明文进行加密,则添加随机 IV 可防止信息泄露。见Encrypting using AES 256, do I need IV?

【讨论】:

猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-11-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-06-02
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多