最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Am I doing AES 256 encryption and decryption Node.js correctly? - Stack Overflow

programmeradmin0浏览0评论

I need to encrypt a chat message that will be stored a database. The data is a string of characters of various lengths. I want to use the native node.js crypto library and use a symmetric encryption protocol such as AES 256. I have concerns are the following:

  1. Is CBC the correct AES mode for this use case for this type of field stored in a TEXT field in MySQL?
  2. Does the key look like it is generated correctly?
  3. Is the IV correct? Is prepending the IV to the encrypted text a proper way to do it or should it be a separate field?
// AES RFC - 
const crypto = require('crypto');

const algorithm = 'aes-256-cbc';
// generate key with crypto.randomBytes(256/8).toString('hex')
const key = '6d858102402dbbeb0f9bb711e3d13a1229684792db4940db0d0e71c08ca602e1';
const IV_LENGTH = 16;

const encrypt = (text) => {
  const iv = crypto.randomBytes(IV_LENGTH);
  const cipher = crypto.createCipheriv(algorithm, Buffer.from(key, 'hex'), iv);
  let encrypted = cipher.update(text);
  encrypted = Buffer.concat([encrypted, cipher.final()]);
  return `${iv.toString('hex')}:${encrypted.toString('hex')}`;
};

const decrypt = (text) => {
  const [iv, encryptedText] = text.split(':').map(part => Buffer.from(part, 'hex'));
  const decipher = crypto.createDecipheriv(algorithm, Buffer.from(key, 'hex'), iv);
  let decrypted = decipher.update(encryptedText);
  decrypted = Buffer.concat([decrypted, decipher.final()]);
  return decrypted.toString();
};

exports.encrypt = encrypt;
exports.decrypt = decrypt;

I need to encrypt a chat message that will be stored a database. The data is a string of characters of various lengths. I want to use the native node.js crypto library and use a symmetric encryption protocol such as AES 256. I have concerns are the following:

  1. Is CBC the correct AES mode for this use case for this type of field stored in a TEXT field in MySQL?
  2. Does the key look like it is generated correctly?
  3. Is the IV correct? Is prepending the IV to the encrypted text a proper way to do it or should it be a separate field?
// AES RFC - https://tools.ietf/html/rfc3602
const crypto = require('crypto');

const algorithm = 'aes-256-cbc';
// generate key with crypto.randomBytes(256/8).toString('hex')
const key = '6d858102402dbbeb0f9bb711e3d13a1229684792db4940db0d0e71c08ca602e1';
const IV_LENGTH = 16;

const encrypt = (text) => {
  const iv = crypto.randomBytes(IV_LENGTH);
  const cipher = crypto.createCipheriv(algorithm, Buffer.from(key, 'hex'), iv);
  let encrypted = cipher.update(text);
  encrypted = Buffer.concat([encrypted, cipher.final()]);
  return `${iv.toString('hex')}:${encrypted.toString('hex')}`;
};

const decrypt = (text) => {
  const [iv, encryptedText] = text.split(':').map(part => Buffer.from(part, 'hex'));
  const decipher = crypto.createDecipheriv(algorithm, Buffer.from(key, 'hex'), iv);
  let decrypted = decipher.update(encryptedText);
  decrypted = Buffer.concat([decrypted, decipher.final()]);
  return decrypted.toString();
};

exports.encrypt = encrypt;
exports.decrypt = decrypt;
Share Improve this question edited Sep 6, 2018 at 23:11 jpotts18 asked Sep 6, 2018 at 21:33 jpotts18jpotts18 5,1115 gold badges33 silver badges32 bronze badges 8
  • Possible duplicate of Node.js encrypts large file using AES – Matt Clark Commented Sep 6, 2018 at 21:34
  • 1 @MattClark I believe this is not a duplicate because it provides an example that uses an IV and demonstrates decryption. – jpotts18 Commented Sep 6, 2018 at 21:39
  • 1 @MattClark does this seem better? This is really my concern. Also saying someone has a "terrible question" and shows "no effort" doesn't seem to match the StackExchange Code of Conduct. meta.stackexchange./conduct – jpotts18 Commented Sep 6, 2018 at 21:51
  • 1 what are your concerns? This looks good to me on first look. – Lux Commented Sep 6, 2018 at 22:20
  • does this code work for you? – Catalyst Commented Sep 6, 2018 at 22:31
 |  Show 3 more ments

1 Answer 1

Reset to default 4

Is CBC the correct AES mode for this use case for this type of field stored in a TEXT field in MySQL?

Well, this depends a bit on your text. But probably yes.

Does the key look like it is generated correctly?

yeah, looks good to me. It should look random and it looks random. Not sure what your concern is here.

Is the IV correct? Is prepending the IV to the encrypted text a proper way to do it or should it be a separate field?

The IV looks good to me. I don't see many reasons why you shouldn't do it this way except one: its not very storage efficient. It would be far more efficient to store the data not as hex string but as binary data! And then you can't just use a colon to seperate the data. So either you know that its the first n bytes or you do a seperate field. Both has upsides and downsides, but both is ok. It's primary a question about style.

发布评论

评论列表(0)

  1. 暂无评论