Перейти к содержанию

Криптография

Выполнение функций криптографии в Node.js обеспечивает встроенный в платформу модуль crypto, который поддерживает алгоритмы для шифрования и расшифровки данных, генерацию сертификатов, хэш-функции и т. д.

Модуль crypto входит не во все сборки Node.js, поэтому его использование в приложении, запускаемом на разных сервера, может быть не всегда возможным. Чтобы проверить доступность модуля, добавьте следующий код.

let crypto;

try {
  crypto = require('crypto');
} catch (err) {
  console.log('Crypto module is unavailable');
}

Для получения списка поддерживаемых в Node.js алгоритмов шифрования, выполните у экземпляра модуля crypto функцию getCiphers().

const crypto = require('crypto');

console.log(crypto.getCiphers());

В рамках данной статьи рассмотрены шифрование и расшифровка данных.

Шифрование данных по заданному алгоритму осуществляется в три этапа:

  • Создание объекта Cipher;
  • Добавление к созданному объекту данных, которые необходимо зашифровать;
  • Завершение процесса шифрования.

Объект Cipher создается вызовом метода crypto.createCipheriv(), который принимает три параметра:

  • алгоритм;
  • ключ;
  • вектор инициализации (необязательный).

Обогащение созданного объекта Cipher данными осуществляется с помощью метода [CipherInstance].update(), которому можно передать следующие аргументы:

  • данные для шифрования;
  • кодировка исходных данных (необязательный);
  • кодировка возвращаемого методом значения (необязательный).

Завершение процесса шифрования осуществляется вызовом метода final(), принимающему кодировку зашифрованных данных.

Рассмотрим пример шифрования данных.

cipher.js

const crypto = require('crypto');

const iv = crypto.randomBytes(16); //генерация вектора инициализации
const key = crypto.scryptSync('secret', 'salt', 32); //генерация ключа

const encyptedData = crypto
  .createCipheriv('aes-256-cbc', key, iv)
  .update('Any data', 'utf8', 'hex')
  .final('hex');

console.log(encryptedData);

В зависимости от используемого алгоритма длина вектора инициализации может отличаться.

Теперь рассмотрим, как расшифровать зашифрованные данные. В качестве зашифрованных данных возьмем результат из предыдущего примера. Последовательность действий та же, только вместо метода createCipher() используется createDecipher().

decipher.js

const crypto = require('crypto');

const iv = crypto.randomBytes(16); //генерация вектора инициализации
const key = crypto.scryptSync('secret', 'salt', 32); //генерация ключа

const decyptedData = crypto
  .createDecipheriv('aes-256-cbc', key, iv)
  .update(encryptedData, 'hex', 'utf8')
  .final('utf8');

console.log(decryptedData); //Any data

Процесс шифрования представляет собой поток. Поэтому пример выше может быть переписан следующим образом.

crypto-stream.js

const crypto = require('crypto');

const iv = crypto.randomBytes(16); //генерация вектора инициализации
const key = crypto.scryptSync('secret', 'salt', 32); //генерация ключа

let cipherStream = crypto.createCipheriv(
  'aes-256-cbc',
  key,
  iv
);

let encryptedData = '';

cipherStream.on(
  'data',
  (data) => (encryptedData += data.toString('hex'))
);

cipherStream.write('Any data');
cipherStream.end();

let decipherStream = crypto.createDecipheriv(
  'aes-256-cbc',
  key,
  iv
);

let decryptedData = '';

decipherStream.on(
  'data',
  (data) => (decryptedData += data)
);
decipherStream.on('end', () => console.log(decryptedData)); //'Any data'

decipherStream.write(encryptedData, 'hex');
decipherStream.end();

Комментарии