EVP_BytesToKey icon indicating copy to clipboard operation
EVP_BytesToKey copied to clipboard

Implementation using modern libraries

Open mahnunchik opened this issue 7 months ago • 0 comments

For all those who are looking for a replacement for the following code:

import AES from 'crypto-js/aes.js';
import Utf8 from 'crypto-js/enc-utf8.js';

function encrypt(data, key) {
  return AES.encrypt(data, key).toString();
}

function decrypt(data, key) {
  return AES.decrypt(data, key).toString(Utf8);
}

const data = 'This is a secret message';
const password = '12345';

data === decrypt(encrypt(data, password), password);

Below is an implementation using modern libraries:

import { md5 } from '@noble/hashes/legacy.js';
import { cbc } from '@noble/ciphers/aes.js';
import { base64 } from '@scure/base'
import {
  abytes,
  bytesToUtf8,
  concatBytes,
  randomBytes,
  utf8ToBytes,
} from '@noble/hashes/utils.js';

export function evpBytesToKey(password, salt = new Uint8Array(0), keyLen = 32, ivLen = 16, count = 1) {
  abytes(password);
  abytes(salt, 0, 8);
  let derived = new Uint8Array(0);
  let block = new Uint8Array(0);

  while (derived.length < (keyLen + ivLen)) {
    block = md5(concatBytes(block, password, salt));
    for (let i = 1; i < count; i++) {
      block = md5(block);
    }
    derived = concatBytes(derived, block);
  }

  return {
    key: derived.slice(0, keyLen),
    iv: derived.slice(keyLen, keyLen + ivLen)
  };
}

export function encrypt(data, password) {
  const salt = randomBytes(8);
  const { key, iv } = evpBytesToKey(utf8ToBytes(password), salt, 32, 16);
  const encrypted = concatBytes(
    utf8ToBytes('Salted__'),
    salt,
    cbc(key, iv).encrypt(utf8ToBytes(data))
  );
  return base64.encode(encrypted);
}

export function decrypt(data, password) {
  const encrypted = base64.decode(data);
  const salt = encrypted.slice(8, 16);
  const { key, iv } = evpBytesToKey(utf8ToBytes(password), salt, 32, 16);
  return bytesToUtf8(cbc(key, iv).decrypt(encrypted.slice(16)));
}

mahnunchik avatar May 23 '25 17:05 mahnunchik