Skip to content

Node v22 encryption is slower and returns different ciphertext than Node v18 — why? #61774

@santhosh-js

Description

@santhosh-js

Hi everyone,

I’m migrating from Node v18 to Node v22 and I noticed two major differences in behavior.


1) Performance difference

Node v18 (fast)

const crypto = require('crypto');
const SECRET = 'SECRET-KEY-FOR-ENCRYPTION';

function encrypt(text) {
  const cipher = crypto.createCipher('aes-256-cbc', SECRET);
  let encrypted = cipher.update(text, 'utf8', 'hex');
  encrypted += cipher.final('hex');
  return encrypted;
}

Running 100 encrypt/decrypt cycles takes ~13ms.

Node v22 (slow)

const crypto = require('crypto');
const SECRET = 'SECRET-KEY-FOR-ENCRYPTION';

function encrypt(text) {
  const iv = crypto.randomBytes(16);
  const key = crypto.scryptSync(SECRET, 'salt', 32);
  const cipher = crypto.createCipheriv('aes-256-cbc', key, iv);

  let encrypted = cipher.update(text, 'utf8', 'hex');
  encrypted += cipher.final('hex');

  return iv.toString('hex') + ':' + encrypted;
}

Running 100 encrypt/decrypt cycles takes 6000+ ms.


2) Different output for same input

With Node v18, encrypting the same text always produced the same ciphertext.
With Node v22, the ciphertext changes every time even for the same input, but decryption works.


Minimal Reproducible Example (copy/paste)

// Node v22 example
const crypto = require('crypto');
const SECRET = 'SECRET-KEY-FOR-ENCRYPTION';

const key = crypto.scryptSync(SECRET, 'salt', 32);

function encrypt(text) {
  const iv = crypto.randomBytes(16);
  const cipher = crypto.createCipheriv('aes-256-cbc', key, iv);

  let encrypted = cipher.update(text, 'utf8', 'hex');
  encrypted += cipher.final('hex');

  return iv.toString('hex') + ':' + encrypted;
}

function decrypt(text) {
  const [ivHex, encrypted] = text.split(':');
  const iv = Buffer.from(ivHex, 'hex');
  const decipher = crypto.createDecipheriv('aes-256-cbc', key, iv);

  let decrypted = decipher.update(encrypted, 'hex', 'utf8');
  decrypted += decipher.final('utf8');
  return decrypted;
}

const input = 'abc123@gmail.com';
const startTime = Date.now();

for (let i = 0; i < 100; i++) {
  const encrypted = encrypt(input);
  decrypt(encrypted);
}

console.log('Time:', Date.now() - startTime);

Questions:

  1. Is this slowdown expected?
  2. Why does createCipheriv produce different output?
  3. Can I make it deterministic again if needed?

Notes:

  • I know createCipher is deprecated and removed in Node v22.
  • This is for Redis storage, not password hashing.

Metadata

Metadata

Assignees

No one assigned

    Labels

    questionIssues that look for answers.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions