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

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

v18.x.x

Стабильность: 2 – Стабильная

АПИ является удовлетворительным. Совместимость с NPM имеет высший приоритет и не будет нарушена кроме случаев явной необходимости.

Модуль node:crypto предоставляет криптографическую функциональность, которая включает набор оберток для функций хэша, HMAC, шифра, расшифровки, подписи и проверки OpenSSL.

1
2
3
4
5
6
7
8
9
const { createHmac } = await import('node:crypto');

const secret = 'abcdefg';
const hash = createHmac('sha256', secret)
    .update('I love cupcakes')
    .digest('hex');
console.log(hash);
// Печать:
// c0fa1bc00531bd78ef38c628449c5102aeabd49b5dc3a2a516ea6ea959d6658e
1
2
3
4
5
6
7
8
9
const { createHmac } = require('node:crypto');

const secret = 'abcdefg';
const hash = createHmac('sha256', secret)
    .update('I love cupcakes')
    .digest('hex');
console.log(hash);
// Печать:
// c0fa1bc00531bd78ef38c628449c5102aeabd49b5dc3a2a516ea6ea959d6658e

Определение отсутствия поддержки криптографии

Возможно, что Node.js будет собран без поддержки модуля node:crypto. В таких случаях попытка импорта из crypto или вызов require('node:crypto') приведет к ошибке.

При использовании CommonJS возникшую ошибку можно перехватить с помощью try/catch:

1
2
3
4
5
6
let crypto;
try {
    crypto = require('node:crypto');
} catch (err) {
    console.error('поддержка крипто отключена!');
}

При использовании лексического ключевого слова ESM import ошибка может быть поймана только в том случае, если обработчик process.on('uncaughtException') зарегистрирован до любой попытки загрузить модуль (например, с помощью модуля предварительной загрузки).

При использовании ESM, если есть вероятность, что код может быть запущен на сборке Node.js, в которой не включена поддержка криптографии, используйте функцию import() вместо лексического ключевого слова import:

1
2
3
4
5
6
let crypto;
try {
    crypto = await import('node:crypto');
} catch (err) {
    console.error('поддержка крипто отключена!');
}

Класс: Certificate

SPKAC - это механизм запроса подписи сертификата, первоначально реализованный компанией Netscape и формально указанный как часть элемента HTML5 keygen.

<keygen> устарел с HTML 5.2, и новые проекты больше не должны использовать этот элемент.

Модуль node:crypto предоставляет класс Certificate для работы с данными SPKAC. Наиболее распространенным использованием является обработка вывода, генерируемого элементом HTML5 <keygen>. Node.js использует OpenSSL's SPKAC implementation внутренне.

Статический метод: Certificate.exportChallenge(spkac[, encoding])

  • spkac {string|ArrayBuffer|Buffer|TypedArray|DataView}
  • encoding <string> кодировка строки spkac.
  • Возвращает: <Buffer> Компонент вызова структуры данных spkac, который включает открытый ключ и вызов.
1
2
3
4
5
const { Certificate } = await import('node:crypto');
const spkac = getSpkacSomehow();
const challenge = Certificate.exportChallenge(spkac);
console.log(challenge.toString('utf8'));
// Выводит: вызов в виде строки UTF8
1
2
3
4
5
const { Certificate } = require('node:crypto');
const spkac = getSpkacSomehow();
const challenge = Certificate.exportChallenge(spkac);
console.log(challenge.toString('utf8'));
// Выводит: вызов в виде строки UTF8

Статический метод: Certificate.exportPublicKey(spkac[, encoding])

  • spkac {string|ArrayBuffer|Buffer|TypedArray|DataView}
  • encoding <string> кодировка строки spkac.
  • Возвращает: <Buffer> Компонент открытого ключа структуры данных spkac, который включает в себя открытый ключ и вызов.
1
2
3
4
5
const { Certificate } = await import('node:crypto');
const spkac = getSpkacSomehow();
const publicKey = Certificate.exportPublicKey(spkac);
console.log(publicKey);
// Печатает: открытый ключ в виде <Буфера ...>
1
2
3
4
5
const { Certificate } = require('node:crypto');
const spkac = getSpkacSomehow();
const publicKey = Certificate.exportPublicKey(spkac);
console.log(publicKey);
// Печатает: открытый ключ в виде <Буфера ...>

Статический метод: Certificate.verifySpkac(spkac[, encoding])

  • spkac {string|ArrayBuffer|Buffer|TypedArray|DataView}
  • encoding <string> кодировка строки spkac.
  • Возвращает: <boolean> true, если данная структура данных spkac корректна, false в противном случае.
1
2
3
4
5
6
import { Buffer } from 'node:buffer';
const { Certificate } = await import('node:crypto');

const spkac = getSpkacSomehow();
console.log(Certificate.verifySpkac(Buffer.from(spkac)));
// Выводит: true или false
1
2
3
4
5
6
const { Buffer } = require('node:buffer');
const { Certificate } = require('node:crypto');

const spkac = getSpkacSomehow();
console.log(Certificate.verifySpkac(Buffer.from(spkac)));
// Выводит: true или false

Legacy API

Стабильность: 0 – устарело или набрало много негативных отзывов

Эта фича является проблемной и ее планируют изменить. Не стоит полагаться на нее. Использование фичи может вызвать ошибки. Не стоит ожидать от нее обратной совместимости.

В качестве унаследованного интерфейса можно создавать новые экземпляры класса crypto.Certificate, как показано в примерах ниже.

new crypto.Certificate()

Экземпляры класса Certificate могут быть созданы с помощью ключевого слова new или путем вызова функции crypto.Certificate():

1
2
3
4
const { Certificate } = await import('node:crypto');

const cert1 = new Certificate();
const cert2 = Certificate();
1
2
3
4
const { Certificate } = require('node:crypto');

const cert1 = new Certificate();
const cert2 = Certificate();

certificate.exportChallenge(spkac[, encoding])

  • spkac {string|ArrayBuffer|Buffer|TypedArray|DataView}
  • encoding <string> кодировка строки spkac.
  • Возвращает: <Buffer> Компонент вызова структуры данных spkac, который включает открытый ключ и вызов.
1
2
3
4
5
6
const { Certificate } = await import('node:crypto');
const cert = Certificate();
const spkac = getSpkacSomehow();
const challenge = cert.exportChallenge(spkac);
console.log(challenge.toString('utf8'));
// Выводит: вызов в виде строки UTF8
1
2
3
4
5
6
const { Certificate } = require('node:crypto');
const cert = Certificate();
const spkac = getSpkacSomehow();
const challenge = cert.exportChallenge(spkac);
console.log(challenge.toString('utf8'));
// Выводит: вызов в виде строки UTF8

certificate.exportPublicKey(spkac[, encoding])

  • spkac {string|ArrayBuffer|Buffer|TypedArray|DataView}
  • encoding <string> кодировка строки spkac.
  • Возвращает: <Buffer> Компонент открытого ключа структуры данных spkac, который включает в себя открытый ключ и вызов.
1
2
3
4
5
6
const { Certificate } = await import('node:crypto');
const cert = Certificate();
const spkac = getSpkacSomehow();
const publicKey = cert.exportPublicKey(spkac);
console.log(publicKey);
// Печатает: открытый ключ в виде <Буфера ...>
1
2
3
4
5
6
const { Certificate } = require('node:crypto');
const cert = Certificate();
const spkac = getSpkacSomehow();
const publicKey = cert.exportPublicKey(spkac);
console.log(publicKey);
// Печатает: открытый ключ в виде <Буфера ...>

certificate.verifySpkac(spkac[, encoding])

  • spkac {string|ArrayBuffer|Buffer|TypedArray|DataView}
  • encoding <string> кодировка строки spkac.
  • Возвращает: <boolean> true, если данная структура данных spkac корректна, false в противном случае.
1
2
3
4
5
6
7
import { Buffer } from 'node:buffer';
const { Certificate } = await import('node:crypto');

const cert = Certificate();
const spkac = getSpkacSomehow();
console.log(cert.verifySpkac(Buffer.from(spkac)));
// Выводит: true или false
1
2
3
4
5
6
7
const { Buffer } = require('node:buffer');
const { Certificate } = require('node:crypto');

const cert = Certificate();
const spkac = getSpkacSomehow();
console.log(cert.verifySpkac(Buffer.from(spkac)));
// Выводит: true или false

Класс: Cipher

  • Расширяет: {stream.Transform}

Экземпляры класса Cipher используются для шифрования данных. Класс может быть использован одним из двух способов:

  • Как поток, который является одновременно читаемым и записываемым, где простые незашифрованные данные записываются для получения зашифрованных данных на читаемой стороне, или
  • используя методы cipher.update() и cipher.final() для создания зашифрованных данных.

Методы crypto.createCipher() или crypto.createCipheriv() используются для создания экземпляров Cipher. Объекты Cipher не должны создаваться напрямую с помощью ключевого слова new.

Пример: Использование объектов Cipher в качестве потоков:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
const { scrypt, randomFill, createCipheriv } = await import(
    'node:crypto'
);

const algorithm = 'aes-192-cbc';
const password = 'Password used to generate key';

// First, we'll generate the key. The key length is dependent on the algorithm.
// In this case for aes192, it is 24 bytes (192 bits).
scrypt(password, 'salt', 24, (err, key) => {
    if (err) throw err;
    // Then, we'll generate a random initialization vector
    randomFill(new Uint8Array(16), (err, iv) => {
        if (err) throw err;

        // Once we have the key and iv, we can create and use the cipher...
        const cipher = createCipheriv(algorithm, key, iv);

        let encrypted = '';
        cipher.setEncoding('hex');

        cipher.on('data', (chunk) => (encrypted += chunk));
        cipher.on('end', () => console.log(encrypted));

        cipher.write('some clear text data');
        cipher.end();
    });
});
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
const {
    scrypt,
    randomFill,
    createCipheriv,
} = require('node:crypto');

const algorithm = 'aes-192-cbc';
const password = 'Password used to generate key';

// First, we'll generate the key. The key length is dependent on the algorithm.
// In this case for aes192, it is 24 bytes (192 bits).
scrypt(password, 'salt', 24, (err, key) => {
    if (err) throw err;
    // Then, we'll generate a random initialization vector
    randomFill(new Uint8Array(16), (err, iv) => {
        if (err) throw err;

        // Once we have the key and iv, we can create and use the cipher...
        const cipher = createCipheriv(algorithm, key, iv);

        let encrypted = '';
        cipher.setEncoding('hex');

        cipher.on('data', (chunk) => (encrypted += chunk));
        cipher.on('end', () => console.log(encrypted));

        cipher.write('some clear text data');
        cipher.end();
    });
});

Пример: Использование Cipher и конвейерных потоков:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
import {
    createReadStream,
    createWriteStream,
} from 'node:fs';

import { pipeline } from 'node:stream';

const { scrypt, randomFill, createCipheriv } = await import(
    'node:crypto'
);

const algorithm = 'aes-192-cbc';
const password = 'Password used to generate key';

// First, we'll generate the key. The key length is dependent on the algorithm.
// In this case for aes192, it is 24 bytes (192 bits).
scrypt(password, 'salt', 24, (err, key) => {
    if (err) throw err;
    // Then, we'll generate a random initialization vector
    randomFill(new Uint8Array(16), (err, iv) => {
        if (err) throw err;

        const cipher = createCipheriv(algorithm, key, iv);

        const input = createReadStream('test.js');
        const output = createWriteStream('test.enc');

        pipeline(input, cipher, output, (err) => {
            if (err) throw err;
        });
    });
});
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
const {
    createReadStream,
    createWriteStream,
} = require('node:fs');

const { pipeline } = require('node:stream');

const {
    scrypt,
    randomFill,
    createCipheriv,
} = require('node:crypto');

const algorithm = 'aes-192-cbc';
const password = 'Password used to generate key';

// First, we'll generate the key. The key length is dependent on the algorithm.
// In this case for aes192, it is 24 bytes (192 bits).
scrypt(password, 'salt', 24, (err, key) => {
    if (err) throw err;
    // Then, we'll generate a random initialization vector
    randomFill(new Uint8Array(16), (err, iv) => {
        if (err) throw err;

        const cipher = createCipheriv(algorithm, key, iv);

        const input = createReadStream('test.js');
        const output = createWriteStream('test.enc');

        pipeline(input, cipher, output, (err) => {
            if (err) throw err;
        });
    });
});

Пример: Использование методов cipher.update() и cipher.final():

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
const { scrypt, randomFill, createCipheriv } = await import(
    'node:crypto'
);

const algorithm = 'aes-192-cbc';
const password = 'Password used to generate key';

// First, we'll generate the key. The key length is dependent on the algorithm.
// In this case for aes192, it is 24 bytes (192 bits).
scrypt(password, 'salt', 24, (err, key) => {
    if (err) throw err;
    // Then, we'll generate a random initialization vector
    randomFill(new Uint8Array(16), (err, iv) => {
        if (err) throw err;

        const cipher = createCipheriv(algorithm, key, iv);

        let encrypted = cipher.update(
            'some clear text data',
            'utf8',
            'hex'
        );
        encrypted += cipher.final('hex');
        console.log(encrypted);
    });
});
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
const {
    scrypt,
    randomFill,
    createCipheriv,
} = require('node:crypto');

const algorithm = 'aes-192-cbc';
const password = 'Password used to generate key';

// First, we'll generate the key. The key length is dependent on the algorithm.
// In this case for aes192, it is 24 bytes (192 bits).
scrypt(password, 'salt', 24, (err, key) => {
    if (err) throw err;
    // Then, we'll generate a random initialization vector
    randomFill(new Uint8Array(16), (err, iv) => {
        if (err) throw err;

        const cipher = createCipheriv(algorithm, key, iv);

        let encrypted = cipher.update(
            'some clear text data',
            'utf8',
            'hex'
        );
        encrypted += cipher.final('hex');
        console.log(encrypted);
    });
});

cipher.final([outputEncoding])

  • outputEncoding <string> кодировка возвращаемого значения.
  • Возвращает: {Буфер | строка} Любое оставшееся зашифрованное содержимое. Если указано outputEncoding, возвращается строка. Если outputEncoding не указан, возвращается Buffer.

После вызова метода cipher.final() объект Cipher больше не может быть использован для шифрования данных. Попытки вызвать cipher.final() более одного раза приведут к возникновению ошибки.

cipher.getAuthTag()

  • Возвращает: <Buffer> При использовании аутентифицированного режима шифрования (в настоящее время поддерживаются GCM, CCM, OCB и chacha20-poly1305) метод cipher.getAuthTag() возвращает Buffer, содержащий тег аутентификации, который был вычислен из заданных данных.

Метод cipher.getAuthTag() следует вызывать только после завершения шифрования с помощью метода cipher.final().

Если параметр authTagLength был установлен при создании экземпляра cipher, эта функция вернет именно authTagLength байт.

cipher.setAAD(buffer[, options])

  • buffer {string|ArrayBuffer|Buffer|TypedArray|DataView}
  • options <Object> stream.transform options
    • plaintextLength <number>
    • encoding <string> Кодировка строки, которую следует использовать, когда buffer является строкой.
  • Возвращает: {Cipher} для цепочки методов.

При использовании аутентифицированного режима шифрования (в настоящее время поддерживаются GCM, CCM, OCB и chacha20-poly1305) метод cipher.setAAD() устанавливает значение, используемое для входного параметра дополнительные аутентифицированные данные (AAD).

Параметр plaintextLength является необязательным для GCM и OCB. При использовании CCM, опция plaintextLength должна быть указана, и ее значение должно соответствовать длине открытого текста в байтах. Смотрите Режим CCM.

Метод cipher.setAAD() должен быть вызван до cipher.update().

cipher.setAutoPadding([autoPadding])

  • autoPadding <boolean> По умолчанию: true.
  • Возвращает: {Cipher} для цепочки методов.

При использовании алгоритмов блочного шифрования класс Cipher будет автоматически добавлять к входным данным прокладки соответствующего размера блока. Чтобы отключить добавление по умолчанию, вызовите cipher.setAutoPadding(false).

Когда autoPadding имеет значение false, длина всех входных данных должна быть кратна размеру блока шифра, иначе cipher.final() выдаст ошибку. Отключение автоматической подшивки полезно при нестандартной подшивке, например, при использовании 0x0 вместо PKCS-подшивки.

Метод cipher.setAutoPadding() должен быть вызван до cipher.final().

cipher.update(data[, inputEncoding][, outputEncoding])

Обновляет шифр с data. Если указан аргумент inputEncoding, то аргумент data является строкой, использующей указанную кодировку. Если аргумент inputEncoding не указан, data должна быть Buffer, TypedArray или DataView. Если data является Buffer, TypedArray, или DataView, то inputEncoding игнорируется.

Параметр outputEncoding определяет формат вывода зашифрованных данных. Если outputEncoding указан, то возвращается строка, использующая указанную кодировку. Если outputEncoding не указан, возвращается Buffer.

Метод cipher.update() может быть вызван несколько раз с новыми данными, пока не будет вызван cipher.final(). Вызов cipher.update() после cipher.final() приведет к возникновению ошибки.

Класс: Decipher

  • Расширяет: {stream.Transform}

Экземпляры класса Decipher используются для расшифровки данных. Класс может быть использован одним из двух способов:

  • Как поток, который является одновременно читаемым и записываемым, где простые зашифрованные данные записываются для получения незашифрованных данных на читаемой стороне, или
  • используя методы decipher.update() и decipher.final() для получения незашифрованных данных.

Методы crypto.createDecipher() или crypto.createDecipheriv() используются для создания экземпляров Decipher. Объекты Decipher не должны создаваться напрямую с помощью ключевого слова new.

Пример: Использование объектов Decipher в качестве потоков:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
import { Buffer } from 'node:buffer';
const { scryptSync, createDecipheriv } = await import(
    'node:crypto'
);

const algorithm = 'aes-192-cbc';
const password = 'Password used to generate key';
// Key length is dependent on the algorithm. In this case for aes192, it is
// 24 bytes (192 bits).
// Use the async `crypto.scrypt()` instead.
const key = scryptSync(password, 'salt', 24);
// The IV is usually passed along with the ciphertext.
const iv = Buffer.alloc(16, 0); // Initialization vector.

const decipher = createDecipheriv(algorithm, key, iv);

let decrypted = '';
decipher.on('readable', () => {
    let chunk;
    while (null !== (chunk = decipher.read())) {
        decrypted += chunk.toString('utf8');
    }
});
decipher.on('end', () => {
    console.log(decrypted);
    // Prints: some clear text data
});

// Encrypted with same algorithm, key and iv.
const encrypted =
    'e5f79c5915c02171eec6b212d5520d44480993d7d622a7c4c2da32f6efda0ffa';
decipher.write(encrypted, 'hex');
decipher.end();
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
const {
    scryptSync,
    createDecipheriv,
} = require('node:crypto');
const { Buffer } = require('node:buffer');

const algorithm = 'aes-192-cbc';
const password = 'Password used to generate key';
// Key length is dependent on the algorithm. In this case for aes192, it is
// 24 bytes (192 bits).
// Use the async `crypto.scrypt()` instead.
const key = scryptSync(password, 'salt', 24);
// The IV is usually passed along with the ciphertext.
const iv = Buffer.alloc(16, 0); // Initialization vector.

const decipher = createDecipheriv(algorithm, key, iv);

let decrypted = '';
decipher.on('readable', () => {
    let chunk;
    while (null !== (chunk = decipher.read())) {
        decrypted += chunk.toString('utf8');
    }
});
decipher.on('end', () => {
    console.log(decrypted);
    // Prints: some clear text data
});

// Encrypted with same algorithm, key and iv.
const encrypted =
    'e5f79c5915c02171eec6b212d5520d44480993d7d622a7c4c2da32f6efda0ffa';
decipher.write(encrypted, 'hex');
decipher.end();

Пример: Использование Decipher и конвейерных потоков:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
import {
    createReadStream,
    createWriteStream,
} from 'node:fs';
import { Buffer } from 'node:buffer';
const { scryptSync, createDecipheriv } = await import(
    'node:crypto'
);

const algorithm = 'aes-192-cbc';
const password = 'Password used to generate key';
// Use the async `crypto.scrypt()` instead.
const key = scryptSync(password, 'salt', 24);
// The IV is usually passed along with the ciphertext.
const iv = Buffer.alloc(16, 0); // Initialization vector.

const decipher = createDecipheriv(algorithm, key, iv);

const input = createReadStream('test.enc');
const output = createWriteStream('test.js');

input.pipe(decipher).pipe(output);
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
const {
    createReadStream,
    createWriteStream,
} = require('node:fs');
const {
    scryptSync,
    createDecipheriv,
} = require('node:crypto');
const { Buffer } = require('node:buffer');

const algorithm = 'aes-192-cbc';
const password = 'Password used to generate key';
// Use the async `crypto.scrypt()` instead.
const key = scryptSync(password, 'salt', 24);
// The IV is usually passed along with the ciphertext.
const iv = Buffer.alloc(16, 0); // Initialization vector.

const decipher = createDecipheriv(algorithm, key, iv);

const input = createReadStream('test.enc');
const output = createWriteStream('test.js');

input.pipe(decipher).pipe(output);

Пример: Использование методов decipher.update() и decipher.final():

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
import { Buffer } from 'node:buffer';
const { scryptSync, createDecipheriv } = await import(
    'node:crypto'
);

const algorithm = 'aes-192-cbc';
const password = 'Password used to generate key';
// Use the async `crypto.scrypt()` instead.
const key = scryptSync(password, 'salt', 24);
// The IV is usually passed along with the ciphertext.
const iv = Buffer.alloc(16, 0); // Initialization vector.

const decipher = createDecipheriv(algorithm, key, iv);

// Encrypted using same algorithm, key and iv.
const encrypted =
    'e5f79c5915c02171eec6b212d5520d44480993d7d622a7c4c2da32f6efda0ffa';
let decrypted = decipher.update(encrypted, 'hex', 'utf8');
decrypted += decipher.final('utf8');
console.log(decrypted);
// Prints: some clear text data
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
const {
    scryptSync,
    createDecipheriv,
} = require('node:crypto');
const { Buffer } = require('node:buffer');

const algorithm = 'aes-192-cbc';
const password = 'Password used to generate key';
// Use the async `crypto.scrypt()` instead.
const key = scryptSync(password, 'salt', 24);
// The IV is usually passed along with the ciphertext.
const iv = Buffer.alloc(16, 0); // Initialization vector.

const decipher = createDecipheriv(algorithm, key, iv);

// Encrypted using same algorithm, key and iv.
const encrypted =
    'e5f79c5915c02171eec6b212d5520d44480993d7d622a7c4c2da32f6efda0ffa';
let decrypted = decipher.update(encrypted, 'hex', 'utf8');
decrypted += decipher.final('utf8');
console.log(decrypted);
// Prints: some clear text data

decipher.final([outputEncoding])

  • outputEncoding <string> кодировка возвращаемого значения.
  • Возвращает: {Буфер | строка} Любое оставшееся расшифрованное содержимое. Если указано outputEncoding, возвращается строка. Если outputEncoding не указан, возвращается Buffer.

После вызова метода decipher.final() объект Decipher больше не может быть использован для расшифровки данных. Попытки вызвать decipher.final() более одного раза приведут к возникновению ошибки.

decipher.setAAD(buffer[, options])

  • buffer {string|ArrayBuffer|Buffer|TypedArray|DataView}
  • options <Object> stream.transform options
    • plaintextLength <number>
    • encoding <string> Кодировка строки, которую следует использовать, когда buffer является строкой.
  • Возвращает: {Decipher} для цепочки методов.

При использовании аутентифицированного режима шифрования (в настоящее время поддерживаются GCM, CCM, OCB и chacha20-poly1305) метод decipher.setAAD() устанавливает значение, используемое для входного параметра дополнительные аутентифицированные данные (AAD).

Аргумент options является необязательным для GCM. При использовании CCM должен быть указан параметр plaintextLength, значение которого должно соответствовать длине шифротекста в байтах. Смотрите Режим CCM.

Метод decipher.setAAD() должен быть вызван до decipher.update().

При передаче строки в качестве буфера, пожалуйста, учитывайте предостережения при использовании строк в качестве входов в криптографические API.

decipher.setAuthTag(buffer[, encoding])

  • буфер {string|Buffer|ArrayBuffer|TypedArray|DataView}
  • encoding <string> Кодировка строки, которую следует использовать, когда buffer является строкой.
  • Возвращает: {Decipher} для цепочки методов.

При использовании аутентифицированного режима шифрования (в настоящее время поддерживаются GCM, CCM, OCB и chacha20-poly1305), метод decipher.setAuthTag() используется для передачи полученного тега аутентификации. Если тег не передан, или если текст шифра был подделан, произойдет ошибка decipher.final(), указывающая на то, что текст шифра должен быть отброшен из-за неудачной аутентификации. Если длина тега недопустима согласно NIST SP 800-38D или не соответствует значению опции authTagLength, decipher.setAuthTag() выдаст ошибку.

Метод decipher.setAuthTag() должен быть вызван до decipher.update() для режима CCM или до decipher.final() для режимов GCM и OCB и chacha20-poly1305. decipher.setAuthTag() может быть вызван только один раз.

При передаче строки в качестве тега аутентификации, пожалуйста, учитывайте предостережения при использовании строк в качестве входов в криптографические API.

decipher.setAutoPadding([autoPadding])

  • autoPadding <boolean> По умолчанию: true.
  • Возвращает: {Decipher} для цепочки методов.

Если данные были зашифрованы без стандартной блочной прокладки, вызов decipher.setAutoPadding(false) отключит автоматическую прокладку, чтобы предотвратить decipher.final() от проверки наличия и удаления прокладки.

Отключение автоматической подстановки будет работать только в том случае, если длина входных данных кратна размеру блока шифра.

Метод decipher.setAutoPadding() должен быть вызван до decipher.final().

decipher.update(data[, inputEncoding][, outputEncoding])

Обновляет расшифровку с data. Если указан аргумент inputEncoding, то аргумент data является строкой, использующей указанную кодировку. Если аргумент inputEncoding не указан, data должна быть Buffer. Если data является Buffer, то inputEncoding игнорируется.

Параметр outputEncoding определяет формат вывода зашифрованных данных. Если outputEncoding указан, то возвращается строка, использующая указанную кодировку. Если outputEncoding не указан, возвращается Buffer.

Метод decipher.update() может быть вызван несколько раз с новыми данными, пока не будет вызван decipher.final(). Вызов decipher.update() после decipher.final() приведет к возникновению ошибки.

Класс: DiffieHellman

Класс DiffieHellman - это утилита для создания обменов ключами Диффи-Хеллмана.

Экземпляры класса DiffieHellman могут быть созданы с помощью функции crypto.createDiffieHellman().

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
import assert from 'node:assert';

const { createDiffieHellman } = await import('node:crypto');

// Генерируем ключи Алисы...
const alice = createDiffieHellman(2048);
const aliceKey = alice.generateKeys();

// Генерируем ключи Боба...
const bob = createDiffieHellman(
    alice.getPrime(),
    alice.getGenerator()
);
const bobKey = bob.generateKeys();

// Обмен и генерация секрета...
const aliceSecret = alice.computeSecret(bobKey);
const bobSecret = bob.computeSecret(aliceKey);

// OK
assert.strictEqual(
    aliceSecret.toString('hex'),
    bobSecret.toString('hex')
);
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
const assert = require('node:assert');

const { createDiffieHellman } = require('node:crypto');

// Генерируем ключи Алисы...
const alice = createDiffieHellman(2048);
const aliceKey = alice.generateKeys();

// Генерируем ключи Боба...
const bob = createDiffieHellman(
    alice.getPrime(),
    alice.getGenerator()
);
const bobKey = bob.generateKeys();

// Обмен и генерация секрета...
const aliceSecret = alice.computeSecret(bobKey);
const bobSecret = bob.computeSecret(aliceKey);

// OK
assert.strictEqual(
    aliceSecret.toString('hex'),
    bobSecret.toString('hex')
);

diffieHellman.computeSecret(otherPublicKey[, inputEncoding][, outputEncoding])

  • otherPublicKey {string|ArrayBuffer|Buffer|TypedArray|DataView}
  • inputEncoding <string> кодировка строки otherPublicKey.
  • outputEncoding <string> кодировка возвращаемого значения.
  • Возвращает: {Буфер | строка}.

Вычисляет общий секрет, используя otherPublicKey в качестве открытого ключа другой стороны, и возвращает вычисленный общий секрет. Предоставленный ключ интерпретируется с использованием указанного inputEncoding, а секрет кодируется с использованием указанного outputEncoding. Если inputEncoding не указан, ожидается, что otherPublicKey будет Buffer, TypedArray или DataView.

Если outputEncoding указан, возвращается строка; в противном случае возвращается Buffer.

diffieHellman.generateKeys([encoding])

  • encoding <string> кодировка возвращаемого значения.
  • Возвращает: {буфер | строка}.

Генерирует значения закрытого и открытого ключей Диффи-Хеллмана и возвращает открытый ключ в указанной кодировке. Этот ключ должен быть передан другой стороне. Если указано encoding, возвращается строка; в противном случае возвращается Buffer.

diffieHellman.getGenerator([encoding])

  • encoding <string> кодировка возвращаемого значения.
  • Возвращает: {Буфер | строка}

Возвращает генератор Диффи-Хеллмана в указанном кодировании. Если указано encoding, возвращается строка; в противном случае возвращается буфер.

diffieHellman.getPrime([encoding])

  • encoding <string> кодировка возвращаемого значения.
  • Возвращает: {Буфер | строка}

Возвращает прайм Диффи-Хеллмана в указанном кодировании. Если кодировка указана, возвращается строка; в противном случае возвращается буфер.

diffieHellman.getPrivateKey([encoding])

  • encoding <string> кодировка возвращаемого значения.
  • Возвращает: {Буфер | строка}

Возвращает закрытый ключ Диффи-Хеллмана в указанной кодировке. Если encoding указан, возвращается строка; в противном случае возвращается Buffer.

diffieHellman.getPublicKey([encoding])

  • encoding <string> кодировка возвращаемого значения.
  • Возвращает: {Буфер | строка}

Возвращает открытый ключ Диффи-Хеллмана в указанной кодировке. Если encoding указан, возвращается строка; в противном случае возвращается Buffer.

diffieHellman.setPrivateKey(privateKey[, encoding])

Устанавливает закрытый ключ Диффи-Хеллмана. Если указан аргумент encoding, ожидается, что privateKey будет строкой. Если аргумент encoding не указан, ожидается, что privateKey будет Buffer, TypedArray или DataView.

diffieHellman.setPublicKey(publicKey[, encoding])

Устанавливает открытый ключ Диффи-Хеллмана. Если указан аргумент encoding, ожидается, что publicKey будет строкой. Если аргумент encoding не указан, ожидается, что publicKey будет Buffer, TypedArray или DataView.

diffieHellman.verifyError

Битовое поле, содержащее любые предупреждения и/или ошибки, возникшие в результате проверки, выполненной во время инициализации объекта DiffieHellman.

Для этого свойства действительны следующие значения (как определено в модуле node:constants):

  • DH_CHECK_P_NOT_SAFE_PRIME.
  • DH_CHECK_P_NOT_PRIME
  • DH_UNABLE_TO_CHECK_GENERATOR
  • DH_NOT_SUITABLE_GENERATOR

Класс: DiffieHellmanGroup

Класс DiffieHellmanGroup принимает в качестве аргумента известную modp-группу. Он работает так же, как и DiffieHellman, за исключением того, что он не позволяет изменять свои ключи после создания. Другими словами, он не реализует методы setPublicKey() и setPrivateKey().

1
2
3
4
const { createDiffieHellmanGroup } = await import(
    'node:crypto'
);
const dh = createDiffieHellmanGroup('modp16');
1
2
const { createDiffieHellmanGroup } = require('node:crypto');
const dh = createDiffieHellmanGroup('modp16');

Поддерживаются следующие группы:

  • 'modp14' (2048 бит, RFC 3526 Раздел 3)
  • 'modp15' (3072 бита, RFC 3526 Раздел 4)
  • 'modp16' (4096 бит, RFC 3526 Раздел 5)
  • 'modp17' (6144 бит, RFC 3526 Раздел 6)
  • 'modp18' (8192 бита, RFC 3526 Раздел 7)

Следующие группы все еще поддерживаются, но устарели (см. Caveats):

  • 'modp1' (768 bits, RFC 2409 Section 6.1)
  • 'modp2' (1024 bits, RFC 2409 Section 6.2)
  • 'modp5' (1536 bits, RFC 3526 Section 2)

Эти устаревшие группы могут быть удалены в будущих версиях Node.js.

Класс: ECDH

Класс ECDH - это утилита для создания обменов ключами Elliptic Curve Diffie-Hellman (ECDH).

Экземпляры класса ECDH могут быть созданы с помощью функции crypto.createECDH().

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
import assert from 'node:assert';

const { createECDH } = await import('node:crypto');

// Генерируем ключи Алисы...
const alice = createECDH('secp521r1');
const aliceKey = alice.generateKeys();

// Генерируем ключи Боба...
const bob = createECDH('secp521r1');
const bobKey = bob.generateKeys();

// Обмен и генерация секрета...
const aliceSecret = alice.computeSecret(bobKey);
const bobSecret = bob.computeSecret(aliceKey);

assert.strictEqual(
    aliceSecret.toString('hex'),
    bobSecret.toString('hex')
);
// OK
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
const assert = require('node:assert');

const { createECDH } = require('node:crypto');

// Генерируем ключи Алисы...
const alice = createECDH('secp521r1');
const aliceKey = alice.generateKeys();

// Генерируем ключи Боба...
const bob = createECDH('secp521r1');
const bobKey = bob.generateKeys();

// Обмен и генерация секрета...
const aliceSecret = alice.computeSecret(bobKey);
const bobSecret = bob.computeSecret(aliceKey);

assert.strictEqual(
    aliceSecret.toString('hex'),
    bobSecret.toString('hex')
);
// OK

Статический метод: ECDH.convertKey(key, curve[, inputEncoding[, outputEncoding[, format]]])

Преобразует открытый ключ EC Диффи-Хеллмана, указанный key и curve в формат, указанный format. Аргумент format задает кодировку точки и может быть сжатым, несжатым или гибридным. Предоставленный ключ интерпретируется с использованием указанного inputEncoding, а возвращаемый ключ кодируется с использованием указанного outputEncoding.

Используйте crypto.getCurves() для получения списка доступных имен кривых. В последних выпусках OpenSSL, openssl ecparam -list_curves также отобразит имя и описание каждой доступной эллиптической кривой.

Если format не указан, точка будет возвращена в формате uncompressed.

Если inputEncoding не указан, ожидается, что key будет Buffer, TypedArray или DataView.

Пример (распаковка ключа):

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
const { createECDH, ECDH } = await import('node:crypto');

const ecdh = createECDH('secp256k1');
ecdh.generateKeys();

const compressedKey = ecdh.getPublicKey(
    'hex',
    'compressed'
);

const uncompressedKey = ECDH.convertKey(
    compressedKey,
    'secp256k1',
    'hex',
    'hex',
    'uncompressed'
);

// Преобразованный ключ и несжатый открытый ключ должны быть одинаковыми
console.log(uncompressedKey === ecdh.getPublicKey('hex'));
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
const { createECDH, ECDH } = require('node:crypto');

const ecdh = createECDH('secp256k1');
ecdh.generateKeys();

const compressedKey = ecdh.getPublicKey(
    'hex',
    'compressed'
);

const uncompressedKey = ECDH.convertKey(
    compressedKey,
    'secp256k1',
    'hex',
    'hex',
    'uncompressed'
);

// Преобразованный ключ и несжатый открытый ключ должны быть одинаковыми
console.log(uncompressedKey === ecdh.getPublicKey('hex'));

ecdh.computeSecret(otherPublicKey[, inputEncoding][, outputEncoding])

  • otherPublicKey {string|ArrayBuffer|Buffer|TypedArray|DataView}
  • inputEncoding <string> кодировка строки otherPublicKey.
  • outputEncoding <string> кодировка возвращаемого значения.
  • Возвращает: {Буфер | строка}.

Вычисляет общий секрет, используя otherPublicKey в качестве открытого ключа другой стороны, и возвращает вычисленный общий секрет. Предоставленный ключ интерпретируется с использованием указанного inputEncoding, а возвращаемый секрет кодируется с использованием указанного outputEncoding. Если inputEncoding не указан, ожидается, что otherPublicKey будет Buffer, TypedArray или DataView.

Если задано outputEncoding, возвращается строка; в противном случае возвращается Buffer.

ecdh.computeSecret будет выдавать ошибку ERR_CRYPTO_ECDH_INVALID_PUBLIC_KEY, если otherPublicKey лежит за пределами эллиптической кривой. Поскольку otherPublicKey обычно передается от удаленного пользователя по незащищенной сети, не забудьте обработать это исключение соответствующим образом.

ecdh.generateKeys([encoding[, format]])

  • encoding <string> кодировка возвращаемого значения.
  • формат <string> По умолчанию: uncompressed.
  • Возвращает: {Буфер | строка}

Генерирует значения закрытого и открытого ключей EC Diffie-Hellman и возвращает открытый ключ в указанном формате и кодировке. Этот ключ должен быть передан другой стороне.

Аргумент формат задает кодировку точки и может быть сжатым или несжатым. Если format не указан, точка будет возвращена в формате 'uncompressed'.

Если указано encoding, возвращается строка; в противном случае возвращается Buffer.

ecdh.getPrivateKey([encoding])

  • encoding <string> кодировка возвращаемого значения.
  • Возвращает: {Буфер | строка} EC Diffie-Hellman в указанном кодировании.

Если указано encoding, возвращается строка; в противном случае возвращается буфер.

ecdh.getPublicKey([encoding][, format])

  • encoding <string> кодировка возвращаемого значения.
  • формат <string> По умолчанию: uncompressed.
  • Возвращает: {Буфер | строка} Открытый ключ EC Diffie-Hellman в указанном кодировании и формате.

Аргумент формат определяет кодировку точки и может быть сжатым или несжатым. Если формат не указан, точка будет возвращена в формате без сжатия.

Если указано encoding, возвращается строка, в противном случае возвращается Buffer.

ecdh.setPrivateKey(privateKey[, encoding])

Устанавливает закрытый ключ EC Diffie-Hellman. Если указано encoding, ожидается, что privateKey будет строкой, в противном случае privateKey будет Buffer, TypedArray или DataView.

Если privateKey не действителен для кривой, указанной при создании объекта ECDH, будет выдана ошибка. При установке закрытого ключа, связанная с ним открытая точка (ключ) также генерируется и устанавливается в объекте ECDH.

ecdh.setPublicKey(publicKey[, encoding])

Стабильность: 0 – устарело или набрало много негативных отзывов

Эта фича является проблемной и ее планируют изменить. Не стоит полагаться на нее. Использование фичи может вызвать ошибки. Не стоит ожидать от нее обратной совместимости.

Устанавливает открытый ключ EC Diffie-Hellman. Если указано encoding, то ожидается, что publicKey будет строкой; в противном случае ожидается Buffer, TypedArray или DataView.

Обычно нет причин вызывать этот метод, поскольку ECDH требует только закрытый ключ и открытый ключ другой стороны для вычисления общего секрета. Обычно вызывается либо ecdh.generateKeys(), либо ecdh.setPrivateKey(). Метод ecdh.setPrivateKey() пытается сгенерировать публичную точку/ключ, связанный с устанавливаемым закрытым ключом.

Пример (получение общего секрета):

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
const { createECDH, createHash } = await import(
    'node:crypto'
);

const alice = createECDH('secp256k1');
const bob = createECDH('secp256k1');

// Это короткий способ указать один из предыдущих закрытых ключей Алисы.
// ключей. Было бы неразумно использовать такой предсказуемый закрытый ключ в реальном // приложении.
// приложении.
alice.setPrivateKey(
    createHash('sha256').update('alice', 'utf8').digest()
);

// Боб использует новую сгенерированную криптографически сильную
// псевдослучайную пару ключей
bob.generateKeys();

const aliceSecret = alice.computeSecret(
    bob.getPublicKey(),
    null,
    'hex'
);
const bobSecret = bob.computeSecret(
    alice.getPublicKey(),
    null,
    'hex'
);

// aliceSecret и bobSecret должны быть одним и тем же значением общего секрета
console.log(aliceSecret === bobSecret);
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
const { createECDH, createHash } = require('node:crypto');

const alice = createECDH('secp256k1');
const bob = createECDH('secp256k1');

// Это короткий способ указать один из предыдущих закрытых ключей Алисы.
// ключей. Было бы неразумно использовать такой предсказуемый закрытый ключ в реальном // приложении.
// приложении.
alice.setPrivateKey(
    createHash('sha256').update('alice', 'utf8').digest()
);

// Боб использует новую сгенерированную криптографически сильную
// псевдослучайную пару ключей
bob.generateKeys();

const aliceSecret = alice.computeSecret(
    bob.getPublicKey(),
    null,
    'hex'
);
const bobSecret = bob.computeSecret(
    alice.getPublicKey(),
    null,
    'hex'
);

// aliceSecret и bobSecret должны быть одним и тем же значением общего секрета
console.log(aliceSecret === bobSecret);

Класс: Hash

  • Расширяет: {stream.Transform}

Класс Hash - это утилита для создания хэш-дайджестов данных. Он может быть использован одним из двух способов:

  • В качестве stream, доступного как для чтения, так и для записи, где данные записываются для получения вычисленного хэш-дайджеста на стороне, доступной для чтения, или
  • используя методы hash.update() и hash.digest() для создания вычисленного хэша.

Метод crypto.createHash() используется для создания экземпляров Hash. Объекты Hash не должны создаваться напрямую с помощью ключевого слова new.

Пример: Использование объектов Hash в качестве потоков:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
const { createHash } = await import('node:crypto');

const hash = createHash('sha256');

hash.on('readable', () => {
    // Только один элемент будет произведен потоком
    // хэш-поток.
    const data = hash.read();
    if (data) {
        console.log(data.toString('hex'));
        // Печатает:
        // 6a2da20943931e9834fc12cfe5bb47bbd9ae43489a30726962b576f4e3993e50
    }
});

hash.write('некоторые данные в хэш');
hash.end();
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
const { createHash } = require('node:crypto');

const hash = createHash('sha256');

hash.on('readable', () => {
    // Только один элемент будет произведен потоком
    // хэш-поток.
    const data = hash.read();
    if (data) {
        console.log(data.toString('hex'));
        // Печатает:
        // 6a2da20943931e9834fc12cfe5bb47bbd9ae43489a30726962b576f4e3993e50
    }
});

hash.write('некоторые данные в хэш');
hash.end();

Пример: Использование Hash и конвейерных потоков:

1
2
3
4
5
6
7
8
import { createReadStream } from 'node:fs';
import { stdout } from 'node:process';
const { createHash } = await import('node:crypto');

const hash = createHash('sha256');

const input = createReadStream('test.js');
input.pipe(hash).setEncoding('hex').pipe(stdout);
1
2
3
4
5
6
7
8
const { createReadStream } = require('node:fs');
const { createHash } = require('node:crypto');
const { stdout } = require('node:process');

const hash = createHash('sha256');

const input = createReadStream('test.js');
input.pipe(hash).setEncoding('hex').pipe(stdout);

Пример: Использование методов hash.update() и hash.digest():

1
2
3
4
5
6
7
8
const { createHash } = await import('node:crypto');

const hash = createHash('sha256');

hash.update('некоторые данные для хэширования');
console.log(hash.digest('hex'));
// Печатает:
// 6a2da20943931e9834fc12cfe5bb47bbd9ae43489a30726962b576f4e3993e50
1
2
3
4
5
6
7
8
const { createHash } = require('node:crypto');

const hash = createHash('sha256');

hash.update('некоторые данные для хэширования');
console.log(hash.digest('hex'));
// Печатает:
// 6a2da20943931e9834fc12cfe5bb47bbd9ae43489a30726962b576f4e3993e50

hash.copy([options])

Создает новый объект Hash, который содержит глубокую копию внутреннего состояния текущего объекта Hash.

Необязательный аргумент options управляет поведением потока. Для хэш-функций XOF, таких как 'shake256', опция outputLength может быть использована для указания желаемой длины вывода в байтах.

При попытке скопировать объект Hash после вызова его метода hash.digest() возникает ошибка.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
// Вычисление скользящего хэша.
const { createHash } = await import('node:crypto');

const hash = createHash('sha256');

hash.update('1');
console.log(hash.copy().digest('hex'));

hash.update('two');
console.log(hash.copy().digest('hex'));

hash.update('three');
console.log(hash.copy().digest('hex'));

// И т.д.
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
// Вычисление скользящего хэша.
const { createHash } = require('node:crypto');

const hash = createHash('sha256');

hash.update('1');
console.log(hash.copy().digest('hex'));

hash.update('two');
console.log(hash.copy().digest('hex'));

hash.update('three');
console.log(hash.copy().digest('hex'));

// И т.д.

hash.digest([encoding])

  • encoding <string> кодировка возвращаемого значения.
  • Возвращает: {Буфер | строка}.

Вычисляет дайджест всех данных, переданных для хеширования (с помощью метода hash.update()). Если указано encoding, то возвращается строка; в противном случае возвращается Buffer.

Объект Hash не может быть использован повторно после вызова метода hash.digest(). Многократные вызовы приведут к возникновению ошибки.

hash.update(data[, inputEncoding])

Обновляет содержимое хэша с заданными data, кодировка которых указана в inputEncoding. Если encoding не указан, а данные являются строкой, то применяется кодировка 'utf8'. Если data является Buffer, TypedArray или DataView, то inputEncoding игнорируется.

Эта функция может вызываться много раз с новыми данными по мере их передачи.

Класс: Hmac

  • Расширяет: {stream.Transform}

Класс Hmac - это утилита для создания криптографических HMAC-дайджестов. Он может быть использован одним из двух способов:

  • В виде stream, доступного как для чтения, так и для записи, где данные записываются для получения вычисленного HMAC-дайджеста на стороне, доступной для чтения, или
  • используя методы hmac.update() и hmac.digest() для создания вычисленного HMAC-дайджеста.

Метод crypto.createHmac() используется для создания экземпляров Hmac. Объекты Hmac не должны создаваться напрямую с помощью ключевого слова new.

Пример: Использование объектов Hmac в качестве потоков:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
const { createHmac } = await import('node:crypto');

const hmac = createHmac('sha256', 'секрет');

hmac.on('readable', () => {
    // Только один элемент будет получен с помощью
    // хэш-поток.
    const data = hmac.read();
    if (data) {
        console.log(data.toString('hex'));
        // Печатает:
        // 7fd04df92f636fd450bc841c9418e5825c17f33ad9c87c518115a45971f7f77e
    }
});

hmac.write('некоторые данные для хэширования');
hmac.end();
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
const { createHmac } = require('node:crypto');

const hmac = createHmac('sha256', 'секрет');

hmac.on('readable', () => {
    // Только один элемент будет получен с помощью
    // хэш-поток.
    const data = hmac.read();
    if (data) {
        console.log(data.toString('hex'));
        // Печатает:
        // 7fd04df92f636fd450bc841c9418e5825c17f33ad9c87c518115a45971f7f77e
    }
});

hmac.write('некоторые данные для хэширования');
hmac.end();

Пример: Использование Hmac и конвейерных потоков:

1
2
3
4
5
6
7
8
import { createReadStream } from 'node:fs';
import { stdout } from 'node:process';
const { createHmac } = await import('node:crypto');

const hmac = createHmac('sha256', 'секрет');

const input = createReadStream('test.js');
input.pipe(hmac).pipe(stdout);
1
2
3
4
5
6
7
8
const { createReadStream } = require('node:fs');
const { createHmac } = require('node:crypto');
const { stdout } = require('node:process');

const hmac = createHmac('sha256', 'секрет');

const input = createReadStream('test.js');
input.pipe(hmac).pipe(stdout);

Пример: Использование методов hmac.update() и hmac.digest():

1
2
3
4
5
6
7
8
const { createHmac } = await import('node:crypto');

const hmac = createHmac('sha256', 'секрет');

hmac.update('некоторые данные для хэширования');
console.log(hmac.digest('hex'));
// Печатает:
// 7fd04df92f636fd450bc841c9418e5825c17f33ad9c87c518115a45971f7f77e
1
2
3
4
5
6
7
8
const { createHmac } = require('node:crypto');

const hmac = createHmac('sha256', 'секрет');

hmac.update('некоторые данные для хэширования');
console.log(hmac.digest('hex'));
// Печатает:
// 7fd04df92f636fd450bc841c9418e5825c17f33ad9c87c518115a45971f7f77e

hmac.digest([encoding])

  • encoding <string> кодировка возвращаемого значения.
  • Возвращает: {Буфер | строка}.

Вычисляет HMAC-дайджест всех данных, переданных с помощью hmac.update(). Если указано encoding, возвращается строка; в противном случае возвращается Buffer;

Объект Hmac не может быть использован повторно после вызова hmac.digest(). Многократные вызовы hmac.digest() приведут к возникновению ошибки.

hmac.update(data[, inputEncoding])

Обновляет содержимое Hmac с заданными data, кодировка которых указана в inputEncoding. Если encoding не указан, а данные являются строкой, то применяется кодировка 'utf8'. Если data является Buffer, TypedArray или DataView, то inputEncoding игнорируется.

Эта функция может вызываться много раз с новыми данными по мере их передачи.

Класс: KeyObject

Node.js использует класс KeyObject для представления симметричного или асимметричного ключа, и каждый вид ключа открывает различные функции. Методы crypto.createSecretKey(), crypto.createPublicKey() и crypto.createPrivateKey() используются для создания экземпляров KeyObject. Объекты KeyObject не должны создаваться непосредственно с помощью ключевого слова new.

Большинство приложений должны рассмотреть возможность использования нового API KeyObject вместо передачи ключей в виде строк или буфера из-за улучшенных функций безопасности.

Экземпляры KeyObject могут быть переданы другим потокам через postMessage(). Получатель получает клонированный KeyObject, и KeyObject не нужно указывать в аргументе transferList.

Статический метод: KeyObject.from(key)

  • key {CryptoKey}
  • Возвращает: {KeyObject}

Пример: Преобразование экземпляра CryptoKey в KeyObject:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
const { KeyObject } = await import('node:crypto');
const { subtle } = globalThis.crypto;

const key = await subtle.generateKey(
    {
        name: 'HMAC',
        hash: 'SHA-256',
        length: 256,
    },
    true,
    ['sign', 'verify']
);

const keyObject = KeyObject.from(key);
console.log(keyObject.symmetricKeySize);
// Печатается: 32 (размер симметричного ключа в байтах)
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
const { KeyObject } = require('node:crypto');
const { subtle } = globalThis.crypto;

(async function () {
    const key = await subtle.generateKey(
        {
            name: 'HMAC',
            hash: 'SHA-256',
            length: 256,
        },
        true,
        ['sign', 'verify']
    );

    const keyObject = KeyObject.from(key);
    console.log(keyObject.symmetricKeySize);
    // Печатается: 32 (размер симметричного ключа в байтах)
})();

keyObject.asymmetricKeyDetails

  • <Object>
    • modulusLength: <number> Размер ключа в битах (RSA, DSA).
    • publicExponent: <bigint> Публичная экспонента (RSA).
    • hashAlgorithm: <string> Имя дайджеста сообщения (RSA-PSS).
    • mgf1HashAlgorithm: <string> Имя дайджеста сообщения, используемого MGF1 (RSA-PSS).
    • saltLength: <number> Минимальная длина соли в байтах (RSA-PSS).
    • divisorLength: <number> Размер q в битах (DSA).
    • namedCurve: <string> Имя кривой (EC).

Это свойство существует только для асимметричных ключей. В зависимости от типа ключа, этот объект содержит информацию о ключе. Никакая информация, полученная через это свойство, не может быть использована для уникальной идентификации ключа или для нарушения безопасности ключа.

Для ключей RSA-PSS, если материал ключа содержит последовательность RSASSA-PSS-params, будут установлены свойства hashAlgorithm, mgf1HashAlgorithm и saltLength.

Другие детали ключа могут быть раскрыты через этот API с помощью дополнительных атрибутов.

keyObject.asymmetricKeyType

Для асимметричных ключей это свойство представляет тип ключа. Поддерживаются следующие типы ключей:

  • rsa (OID 1.2.840.113549.1.1.1)
  • rsa-pss (OID 1.2.840.113549.1.1.10)
  • dsa (OID 1.2.840.10040.4.1)
  • ec (OID 1.2.840.10045.2.1)
  • x25519 (OID 1.3.101.110)
  • x448 (OID 1.3.101.111)
  • ed25519 (OID 1.3.101.112)
  • ed448 (OID 1.3.101.113)
  • dh (OID 1.2.840.113549.1.3.1)

Это свойство не определено для нераспознанных типов KeyObject и симметричных ключей.

keyObject.export([options])

  • options: <Object>
  • Возвращает: {строка | буфер | объект}.

Для симметричных ключей можно использовать следующие параметры кодировки:

  • формат: <string>. Должно быть буфер (по умолчанию) или jwk.

Для открытых ключей можно использовать следующие параметры кодировки:

  • type: <string>. Должно быть одно из 'pkcs1' (только RSA) или 'spki'.
  • формат: <string> Должен быть 'pem', 'der' или 'jwk'.

Для закрытых ключей можно использовать следующие параметры кодировки:

  • type: <string>. Должно быть одно из 'pkcs1' (только RSA), 'pkcs8' или 'sec1' (только EC).
  • формат: <string>. Должен быть 'pem', 'der' или 'jwk'.
  • шифр: <string>. Если указано, закрытый ключ будет зашифрован с помощью заданных шифра и пасфразы с использованием PKCS#5 v2.0 шифрования на основе пароля.
  • passphrase: {строка | буфер} Парольная фраза, используемая для шифрования, см. шифр.

Тип результата зависит от выбранного формата кодирования, при PEM результатом будет строка, при DER - буфер, содержащий данные, закодированные как DER, при JWK - объект.

Если выбран формат кодирования JWK, все остальные варианты кодирования игнорируются.

Ключи типов PKCS#1, SEC1 и PKCS#8 могут быть зашифрованы с помощью комбинации опций шифр и формат. PKCS#8 type можно использовать с любым format для шифрования любого алгоритма ключа (RSA, EC или DH), указав cipher. PKCS#1 и SEC1 могут быть зашифрованы путем указания шифра только при использовании формата PEM. Для максимальной совместимости используйте PKCS#8 для зашифрованных закрытых ключей. Поскольку PKCS#8 определяет свой собственный механизм шифрования, шифрование на уровне PEM не поддерживается при шифровании ключа PKCS#8. См. RFC 5208 для шифрования PKCS#8 и RFC 1421 для шифрования PKCS#1 и SEC1.

keyObject.equals(otherKeyObject)

  • otherKeyObject: {KeyObject} Объект KeyObject, с которым сравнивается keyObject.
  • Возвращает: <boolean>

Возвращает true или false в зависимости от того, имеют ли ключи абсолютно одинаковый тип, значение и параметры. Этот метод не является постоянным временем.

keyObject.symmetricKeySize

Для секретных ключей это свойство представляет размер ключа в байтах. Для асимметричных ключей это свойство не определено.

keyObject.type

В зависимости от типа данного KeyObject, это свойство является либо 'secret' для секретных (симметричных) ключей, либо 'public' для открытых (асимметричных) ключей, либо 'private' для закрытых (асимметричных) ключей.

Класс: Sign

Класс Sign - это утилита для генерации подписей. Он может быть использован одним из двух способов:

  • Как записываемый stream, в который записываются данные, подлежащие подписи, а метод sign.sign() используется для генерации и возврата подписи, или
  • Использование методов sign.update() и sign.sign() для создания подписи.

Метод crypto.createSign() используется для создания экземпляров Sign. Аргументом является строковое имя используемой хэш-функции. Объекты Sign не должны создаваться напрямую с помощью ключевого слова new.

Пример: Использование объектов Sign и Verify в качестве потоков:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
const {
    generateKeyPairSync,
    createSign,
    createVerify,
} = await import('node:crypto');

const { privateKey, publicKey } = generateKeyPairSync(
    'ec',
    {
        namedCurve: 'sect239k1',
    }
);

const sign = createSign('SHA256');
sign.write('некоторые данные для подписи');
sign.end();
const signature = sign.sign(privateKey, 'hex');

const verify = createVerify('SHA256');
verify.write('некоторые данные для подписи');
verify.end();
console.log(verify.verify(publicKey, signature, 'hex'));
// Выводит: true
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
const {
    generateKeyPairSync,
    createSign,
    createVerify,
} = require('node:crypto');

const { privateKey, publicKey } = generateKeyPairSync(
    'ec',
    {
        namedCurve: 'sect239k1',
    }
);

const sign = createSign('SHA256');
sign.write('некоторые данные для подписи');
sign.end();
const signature = sign.sign(privateKey, 'hex');

const verify = createVerify('SHA256');
verify.write('некоторые данные для подписи');
verify.end();
console.log(verify.verify(publicKey, signature, 'hex'));
// Выводит: true

Пример: Использование методов sign.update() и verify.update():

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
const {
    generateKeyPairSync,
    createSign,
    createVerify,
} = await import('node:crypto');

const { privateKey, publicKey } = generateKeyPairSync(
    'rsa',
    {
        modulusLength: 2048,
    }
);

const sign = createSign('SHA256');
sign.update('некоторые данные для подписи');
sign.end();
const signature = sign.sign(privateKey);

const verify = createVerify('SHA256');
verify.update('некоторые данные для подписи');
verify.end();
console.log(verify.verify(publicKey, signature));
// Выводит: true
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
const {
    generateKeyPairSync,
    createSign,
    createVerify,
} = require('node:crypto');

const { privateKey, publicKey } = generateKeyPairSync(
    'rsa',
    {
        modulusLength: 2048,
    }
);

const sign = createSign('SHA256');
sign.update('некоторые данные для подписи');
sign.end();
const signature = sign.sign(privateKey);

const verify = createVerify('SHA256');
verify.update('некоторые данные для подписи');
verify.end();
console.log(verify.verify(publicKey, signature));
// Выводит: true

sign.sign(privateKey[, outputEncoding])

  • privateKey {Object|string|ArrayBuffer|Buffer|TypedArray|DataView|KeyObject|CryptoKey}
  • outputEncoding <string> кодировка возвращаемого значения.
  • Возвращает: {Буфер | строка}.

Вычисляет подпись на всех переданных данных, используя либо sign.update(), либо sign.write().

Если privateKey не является KeyObject, эта функция ведет себя так, как если бы privateKey был передан в crypto.createPrivateKey(). Если это объект, могут быть переданы следующие дополнительные свойства:

  • dsaEncoding <string> Для DSA и ECDSA этот параметр определяет формат генерируемой подписи. Он может быть одним из следующих:

    • der (по умолчанию): DER-кодирование ASN.1 структуры подписи в кодировке (r, s).
    • 'ieee-p1363': Формат подписи r || s, предложенный в IEEE-P1363.
  • padding <integer> Необязательное значение прокладки для RSA, одно из следующих:

    • crypto.constants.RSA_PKCS1_PADDING (по умолчанию)
    • crypto.constants.RSA_PKCS1_PSS_PADDING

    RSA_PKCS1_PSS_PADDING будет использовать MGF1 с той же хэш-функцией, которая используется для подписи сообщения, как указано в разделе 3.1 RFC 4055, если только хэш-функция MGF1 не была указана как часть ключа в соответствии с разделом 3.3 RFC 4055.

  • saltLength <integer> Длина соли для случая, когда padding равен RSA_PKCS1_PSS_PADDING. Специальное значение crypto.constants.RSA_PSS_SALTLEN_DIGEST устанавливает длину соли в размер дайджеста, crypto.constants.RSA_PSS_SALTLEN_MAX_SIGN (по умолчанию) - в максимально допустимое значение.

Если указано outputEncoding, возвращается строка; в противном случае возвращается буфер.

Объект Sign не может быть повторно использован после вызова метода sign.sign(). Многократные вызовы метода sign.sign() приведут к возникновению ошибки.

sign.update(data[, inputEncoding])

Обновляет содержимое Sign с заданными data, кодировка которых указана в inputEncoding. Если encoding не указан, и данные являются строкой, то применяется кодировка 'utf8'. Если data является Buffer, TypedArray или DataView, то inputEncoding игнорируется.

Эта функция может вызываться много раз с новыми данными по мере их передачи.

Класс: Verify

Класс Verify - это утилита для проверки подписей. Он может быть использован одним из двух способов:

  • Как записываемый stream, где записанные данные используются для проверки на соответствие предоставленной подписи, или
  • Используя методы verify.update() и verify.verify() для проверки подписи.

Метод crypto.createVerify() используется для создания экземпляров Verify. Объекты Verify не должны создаваться напрямую с помощью ключевого слова new.

Примеры смотрите в Sign.

verify.update(data[, inputEncoding])

Обновляет содержимое Verify с заданными data, кодировка которых указана в inputEncoding. Если inputEncoding не указан, а данные являются строкой, применяется кодировка 'utf8'. Если data является Buffer, TypedArray или DataView, то inputEncoding игнорируется.

Эта функция может вызываться много раз с новыми данными по мере их передачи.

verify.verify(object, signature[, signatureEncoding])

  • object {Object|string|ArrayBuffer|Buffer|TypedArray|DataView|KeyObject|CryptoKey}
  • signature {string|ArrayBuffer|Buffer|TypedArray|DataView}
  • signatureEncoding <string> кодировка строки signature.
  • Возвращает: <boolean> true или false в зависимости от достоверности подписи для данных и открытого ключа.

Проверяет предоставленные данные с помощью заданных объекта и подписи.

Если object не является KeyObject, эта функция ведет себя так, как если бы object был передан в crypto.createPublicKey(). Если это объект, то могут быть переданы следующие дополнительные свойства:

  • dsaEncoding <string> Для DSA и ECDSA этот параметр определяет формат подписи. Он может быть одним из следующих:

    • 'der (по умолчанию): DER-кодирование ASN.1 структуры подписи в кодировке (r, s).
    • 'ieee-p1363': Формат подписи r || s, предложенный в IEEE-P1363.
  • padding <integer> Необязательное значение прокладки для RSA, одно из следующих:

    • crypto.constants.RSA_PKCS1_PADDING (по умолчанию)
    • crypto.constants.RSA_PKCS1_PSS_PADDING

    RSA_PKCS1_PSS_PADDING будет использовать MGF1 с той же хэш-функцией, которая используется для проверки сообщения, как указано в разделе 3.1 RFC 4055, если только хэш-функция MGF1 не была указана как часть ключа в соответствии с разделом 3.3 RFC 4055.

  • saltLength <integer> Длина соли для случая, когда padding равен RSA_PKCS1_PSS_PADDING. Специальное значение crypto.constants.RSA_PSS_SALTLEN_DIGEST устанавливает длину соли в соответствии с размером дайджеста, crypto.constants.RSA_PSS_SALTLEN_AUTO (по умолчанию) заставляет ее определяться автоматически.

Аргумент signature - это ранее вычисленная подпись для данных в кодировке signatureEncoding. Если указано signatureEncoding, то ожидается, что signature будет строкой, в противном случае signature будет Buffer, TypedArray или DataView.

Объект verify не может быть использован повторно после вызова verify.verify(). Многократные вызовы verify.verify() приведут к возникновению ошибки.

Поскольку открытые ключи могут быть производными от закрытых ключей, вместо открытого ключа можно передать закрытый ключ.

Класс: X509Certificate

Инкапсулирует сертификат X509 и предоставляет доступ к его информации только для чтения.

1
2
3
4
5
6
7
const { X509Certificate } = await import('node:crypto');

const x509 = new X509Certificate(
    '{... pem encoded cert ...}'
);

console.log(x509.subject);
1
2
3
4
5
6
7
const { X509Certificate } = require('node:crypto');

const x509 = new X509Certificate(
    '{... pem encoded cert ...}'
);

console.log(x509.subject);

new X509Certificate(buffer)

  • buffer {string|TypedArray|Buffer|DataView} Сертификат X509 в кодировке PEM или DER.

x509.ca

  • Тип: <boolean> Будет true, если это сертификат центра сертификации (ЦС).

x509.checkEmail(email[, options])

  • email <string>
  • options <Object>
    • subject <string> по умолчанию, всегда, или никогда. По умолчанию: `'по умолчанию'*.
  • Возвращает: {string|undefined} Возвращает email, если сертификат соответствует, undefined, если не соответствует.

Проверяет, соответствует ли сертификат заданному адресу электронной почты.

Если параметр 'subject' неопределен или установлен в 'default', тема сертификата рассматривается только в том случае, если альтернативное расширение имени subject либо не существует, либо не содержит никаких адресов электронной почты.

Если опция 'subject' установлена в 'always' и если альтернативное расширение имени subject либо не существует, либо не содержит подходящего адреса электронной почты, то рассматривается тема сертификата.

Если опция 'subject' установлена в 'never', тема сертификата никогда не рассматривается, даже если сертификат не содержит альтернативных имен темы.

x509.checkHost(name[, options])

  • name <string>
  • options <Object>
    • subject <string> по умолчанию, всегда, или никогда. По умолчанию: `'по умолчанию'*.
    • wildcards <boolean> По умолчанию: true.
    • partialWildcards <boolean> По умолчанию: true.
    • multiLabelWildcards <boolean> По умолчанию: false.
    • singleLabelSubdomains <boolean> По умолчанию: false.
  • Возвращает: {string|undefined} Возвращает имя субъекта, соответствующее name, или undefined, если ни одно имя субъекта не соответствует name.

Проверяет, соответствует ли сертификат заданному имени хоста.

Если сертификат соответствует заданному имени хоста, возвращается соответствующее имя субъекта. Возвращаемое имя может быть точным (например, foo.example.com) или содержать подстановочные знаки (например, *.example.com). Поскольку сравнение имен хостов не чувствительно к регистру, возвращаемое имя субъекта может отличаться от заданного name по капитализации.

Если опция 'subject' не определена или установлена в 'default', субъект сертификата рассматривается только в том случае, если расширение альтернативного имени субъекта либо не существует, либо не содержит никаких имен DNS. Такое поведение соответствует RFC 2818 ("HTTP Over TLS").

Если опция 'subject' установлена в 'always' и если расширение альтернативного имени субъекта либо не существует, либо не содержит подходящего DNS-имени, рассматривается субъект сертификата.

Если опция 'subject' установлена в 'never', субъект сертификата никогда не рассматривается, даже если сертификат не содержит альтернативных имен субъекта.

x509.checkIP(ip)

  • ip <string>
  • Возвращает: {string|undefined} Возвращает ip, если сертификат соответствует, undefined, если не соответствует.

Проверяет соответствие сертификата заданному IP-адресу (IPv4 или IPv6).

Учитываются только RFC 5280 iPAddress предметные альтернативные имена, которые должны точно совпадать с заданным ip адресом. Другие альтернативные имена субъектов, а также поле subject сертификата игнорируются.

x509.checkIssued(otherCert)

  • otherCert {X509Certificate}
  • Возвращает: <boolean>

Проверяет, был ли этот сертификат выпущен данным otherCert.

x509.checkPrivateKey(privateKey)

  • privateKey {KeyObject} Закрытый ключ.
  • Возвращает: <boolean>.

Проверяет, соответствует ли открытый ключ данного сертификата заданному закрытому ключу.

x509.fingerprint

Отпечаток SHA-1 этого сертификата.

Поскольку SHA-1 является криптографически неполноценным и поскольку безопасность SHA-1 значительно хуже, чем у алгоритмов, которые обычно используются для подписания сертификатов, подумайте об использовании x509.fingerprint256 вместо этого.

x509.fingerprint256

Отпечаток SHA-256 этого сертификата.

x509.fingerprint512

Отпечаток SHA-512 этого сертификата.

Поскольку вычисление отпечатка SHA-256 обычно происходит быстрее, а его размер в два раза меньше, чем у отпечатка SHA-512, x509.fingerprint256 может быть лучшим выбором. Хотя SHA-512, предположительно, обеспечивает более высокий уровень безопасности в целом, безопасность SHA-256 соответствует безопасности большинства алгоритмов, которые обычно используются для подписания сертификатов.

x509.infoAccess

Текстовое представление расширения доступа к информации об авторитете сертификата.

Это список описаний доступа, разделенных переводом строки. Каждая строка начинается с метода доступа и вида места доступа, затем следует двоеточие и значение, связанное с местом доступа.

После префикса, обозначающего метод доступа и вид места доступа, оставшаяся часть каждой строки может быть заключена в кавычки, чтобы указать, что значение является литералом строки JSON. Для обратной совместимости Node.js использует строковые литералы JSON в этом свойстве только при необходимости, чтобы избежать двусмысленности. Код сторонних разработчиков должен быть готов к обработке обоих возможных форматов ввода.

x509.issuer

Идентификатор эмитента, включенный в данный сертификат.

x509.issuerCertificate

  • Тип: {X509Certificate}

Сертификат эмитента или undefined, если сертификат эмитента недоступен.

x509.keyUsage

Массив с подробным описанием использования ключей для этого сертификата.

x509.publicKey

  • Тип: {KeyObject}

Открытый ключ {KeyObject} для этого сертификата.

x509.raw

Буфер, содержащий DER-кодировку данного сертификата.

x509.serialNumber

Серийный номер данного сертификата.

Серийные номера присваиваются центрами сертификации и не являются уникальной идентификацией сертификатов. Вместо этого используйте x509.fingerprint256 в качестве уникального идентификатора.

x509.subject

Полный субъект этого сертификата.

x509.subjectAltName

Альтернативное имя субъекта, указанное для этого сертификата.

Это список альтернативных имен субъектов, разделенных запятыми. Каждая запись начинается со строки, определяющей вид альтернативного имени субъекта, за которой следует двоеточие и значение, связанное с этой записью.

Ранние версии Node.js ошибочно полагали, что безопасно разделять это свойство на двухсимвольную последовательность ', ' (см. CVE-2021-44532). Однако как вредоносные, так и легитимные сертификаты могут содержать альтернативные имена субъектов, включающие эту последовательность при представлении в виде строки.

После префикса, обозначающего тип записи, оставшаяся часть каждой записи может быть заключена в кавычки, чтобы указать, что значение является строковым литералом JSON. Для обратной совместимости Node.js использует строковые литералы JSON в этом свойстве только при необходимости, чтобы избежать двусмысленности. Код сторонних разработчиков должен быть готов к обработке обоих возможных форматов ввода.

x509.toJSON()

Не существует стандартной кодировки JSON для сертификатов X509. Метод toJSON() возвращает строку, содержащую сертификат в кодировке PEM.

x509.toLegacyObject()

Возвращает информацию об этом сертификате, используя кодировку legacy certificate object.

x509.toString()

Возвращает сертификат в PEM-кодировке.

x509.validFrom

Дата/время, с которой данный сертификат считается действительным.

x509.validTo

Дата/время, до которого этот сертификат считается действительным.

x509.verify(publicKey)

  • publicKey {KeyObject} Открытый ключ.
  • Возвращает: <boolean>

Проверяет, что данный сертификат был подписан данным открытым ключом. Не выполняет никаких других проверок сертификата.

Методы и свойства модуля node:crypto

crypto.constants

Объект, содержащий часто используемые константы для операций, связанных с криптографией и безопасностью. Конкретные константы, определенные в настоящее время, описаны в Crypto constants.

crypto.DEFAULT_ENCODING

Стабильность: 0 – устарело или набрало много негативных отзывов

Эта фича является проблемной и ее планируют изменить. Не стоит полагаться на нее. Использование фичи может вызвать ошибки. Не стоит ожидать от нее обратной совместимости.

Кодировка по умолчанию для функций, которые могут принимать либо строки, либо buffers. Значение по умолчанию - buffer, что заставляет методы по умолчанию использовать объекты `Buffer'.

Механизм crypto.DEFAULT_ENCODING предусмотрен для обратной совместимости с устаревшими программами, которые ожидают, что 'latin1' будет кодировкой по умолчанию.

Новые приложения должны ожидать, что по умолчанию будет использоваться кодировка 'buffer'.

Это свойство устарело.

crypto.fips

Стабильность: 0 – устарело или набрало много негативных отзывов

Эта фича является проблемной и ее планируют изменить. Не стоит полагаться на нее. Использование фичи может вызвать ошибки. Не стоит ожидать от нее обратной совместимости.

Свойство для проверки и контроля того, используется ли в настоящее время FIPS-совместимый криптопровайдер. Установка значения true требует FIPS-сборки Node.js.

Это свойство устарело. Вместо него используйте crypto.setFips() и crypto.getFips().

crypto.checkPrime(candidate[, options], callback)

  • candidate {ArrayBuffer|SharedArrayBuffer|TypedArray|Buffer|DataView|bigint} A possible prime encoded as a sequence of big endian octets of arbitrary length.
  • options <Object>
    • checks <number> The number of Miller-Rabin probabilistic primality iterations to perform. When the value is 0 (zero), a number of checks is used that yields a false positive rate of at most 2-64 for random input. Care must be used when selecting a number of checks. Refer to the OpenSSL documentation for the BN_is_prime_ex function nchecks options for more details. Default: 0
  • callback <Function>
    • err <Error> Set to an <Error> object if an error occurred during check.
    • result <boolean> true if the candidate is a prime with an error probability less than 0.25 ** options.checks.

Checks the primality of the candidate.

crypto.checkPrimeSync(candidate[, options])

  • candidate {ArrayBuffer|SharedArrayBuffer|TypedArray|Buffer|DataView|bigint} Возможный прайм, закодированный как последовательность октетов big endian произвольной длины.
  • options <Object>
    • checks <number> The number of Miller-Rabin probabilistic primality iterations to perform. Если значение равно 0 (ноль), используется такое количество проверок, которое дает коэффициент ложных срабатываний не более 2-64 для случайного ввода. При выборе количества проверок следует проявлять осторожность. Более подробную информацию см. в документации OpenSSL для опций функции nchecks BN_is_prime_ex. По умолчанию: 0.
  • Возвращает: <boolean> true, если кандидат является простым с вероятностью ошибки меньше чем 0.25 ** options.checks.

Проверяет первичность candidate.

crypto.createCipher(algorithm, password[, options])

Стабильность: 0 – устарело или набрало много негативных отзывов

Эта фича является проблемной и ее планируют изменить. Не стоит полагаться на нее. Использование фичи может вызвать ошибки. Не стоит ожидать от нее обратной совместимости.

Используйте crypto.createCipheriv() вместо этого.

Создает и возвращает объект Cipher, использующий заданные алгоритм и пароль.

Аргумент options управляет поведением потока и является необязательным, за исключением случаев, когда используется шифр в режиме CCM или OCB (например, 'aes-128-ccm'). В этом случае опция authTagLength является обязательной и определяет длину тега аутентификации в байтах, см. CCM mode. В режиме GCM опция authTagLength не обязательна, но может использоваться для установки длины тега аутентификации, который будет возвращен функцией getAuthTag() и по умолчанию составляет 16 байт. Для chacha20-poly1305 опция authTagLength по умолчанию равна 16 байтам.

Алгоритм algorithm зависит от OpenSSL, примеры: 'aes192' и т.д. В последних выпусках OpenSSL, openssl list -cipher-algorithms покажет доступные алгоритмы шифрования.

Пароль password используется для получения ключа шифрования и вектора инициализации (IV). The value must be either a 'latin1' encoded string, a Buffer, a TypedArray, or a DataView.

Эта функция семантически небезопасна для всех поддерживаемых шифров и фатально ошибочна для шифров в режиме счетчика (таких как CTR, GCM или CCM).

Реализация crypto.createCipher() создает ключи с помощью функции OpenSSL EVP_BytesToKey с алгоритмом дайджеста MD5, одной итерацией и без соли. Отсутствие соли позволяет проводить атаки по словарю, поскольку один и тот же пароль всегда создает один и тот же ключ. Малое количество итераций и некриптографически защищенный алгоритм хэширования позволяют проверять пароли очень быстро.

В соответствии с рекомендацией OpenSSL использовать более современный алгоритм вместо EVP_BytesToKey, разработчикам рекомендуется самостоятельно определять ключ и IV с помощью crypto.scrypt() и использовать crypto.createCipheriv() для создания объекта Cipher. Пользователи не должны использовать шифры с режимом счетчика (например, CTR, GCM или CCM) в crypto.createCipher(). При их использовании выдается предупреждение, чтобы избежать риска повторного использования IV, приводящего к уязвимостям. Для случая, когда IV повторно используется в GCM, смотрите Nonce-Disrespecting Adversaries для подробностей.

crypto.createCipheriv(algorithm, key, iv[, options])

  • алгоритм <string>
  • key {string|ArrayBuffer|Buffer|TypedArray|DataView|KeyObject|CryptoKey}
  • iv {string|ArrayBuffer|Buffer|TypedArray|DataView|null}
  • options <Object> stream.transform options
  • Возвращает: {Cipher}

Создает и возвращает объект Cipher с заданным алгоритмом, ключом и вектором инициализации (iv).

Аргумент options управляет поведением потока и является необязательным, за исключением случаев, когда используется шифр в режиме CCM или OCB (например, 'aes-128-ccm'). В этом случае опция authTagLength является обязательной и определяет длину тега аутентификации в байтах, см. CCM mode. В режиме GCM опция authTagLength не обязательна, но может использоваться для установки длины тега аутентификации, который будет возвращен функцией getAuthTag() и по умолчанию составляет 16 байт. Для chacha20-poly1305 опция authTagLength по умолчанию равна 16 байтам.

Алгоритм algorithm зависит от OpenSSL, примеры: 'aes192' и т. д. В последних выпусках OpenSSL опция openssl list -cipher-algorithms покажет доступные алгоритмы шифрования.

Ключ key - это необработанный ключ, используемый алгоритмом, а iv - это вектор инициализации. Оба аргумента должны быть строками в кодировке 'utf8, Buffers, TypedArray или DataView. Ключ может быть KeyObject типа secret. Если шифру не требуется вектор инициализации, iv может быть null.

При передаче строк для key или iv, пожалуйста, учитывайте предостережения при использовании строк в качестве входов в криптографические API.

Векторы инициализации должны быть непредсказуемыми и уникальными; в идеале они должны быть криптографически случайными. Они не обязательно должны быть секретными: IV обычно просто добавляются к шифротекстовым сообщениям в незашифрованном виде. Может показаться противоречивым, что что-то должно быть непредсказуемым и уникальным, но не должно быть секретным; помните, что атакующий не должен иметь возможности заранее предсказать, каким будет данный IV.

crypto.createDecipher(algorithm, password[, options])

Стабильность: 0 – устарело или набрало много негативных отзывов

Эта фича является проблемной и ее планируют изменить. Не стоит полагаться на нее. Использование фичи может вызвать ошибки. Не стоит ожидать от нее обратной совместимости.

Вместо этого используйте crypto.createDecipheriv().

Создает и возвращает объект Decipher, использующий заданный алгоритм и пароль (ключ).

Аргумент options управляет поведением потока и является необязательным, за исключением случаев, когда используется шифр в режиме CCM или OCB (например, 'aes-128-ccm'). В этом случае опция authTagLength является обязательной и определяет длину тега аутентификации в байтах, см. CCM mode. Для chacha20-poly1305 опция authTagLength по умолчанию равна 16 байтам.

Эта функция семантически небезопасна для всех поддерживаемых шифров и фатально небезопасна для шифров в режиме счетчика (таких как CTR, GCM или CCM).

Реализация crypto.createDecipher() извлекает ключи с помощью функции OpenSSL EVP_BytesToKey с алгоритмом дайджеста MD5, одной итерацией и без соли. Отсутствие соли позволяет проводить атаки по словарю, так как один и тот же пароль всегда создает один и тот же ключ. Малое количество итераций и некриптографически безопасный алгоритм хэширования позволяют проверять пароли очень быстро.

В соответствии с рекомендацией OpenSSL использовать более современный алгоритм вместо EVP_BytesToKey, разработчикам рекомендуется самостоятельно определять ключ и IV с помощью crypto.scrypt() и использовать crypto.createDecipheriv() для создания объекта Decipher.

crypto.createDecipheriv(algorithm, key, iv[, options])

  • алгоритм <string>
  • key {string|ArrayBuffer|Buffer|TypedArray|DataView|KeyObject|CryptoKey}
  • iv {string|ArrayBuffer|Buffer|TypedArray|DataView|null}
  • options <Object> stream.transform options
  • Возвращает: {Decipher}

Создает и возвращает объект Decipher, который использует заданный алгоритм, ключ и вектор инициализации (iv).

Аргумент options управляет поведением потока и является необязательным, за исключением случаев, когда используется шифр в режиме CCM или OCB (например, 'aes-128-ccm'). В этом случае опция authTagLength является обязательной и определяет длину тега аутентификации в байтах, см. CCM mode. В режиме GCM опция authTagLength не требуется, но может быть использована для ограничения принимаемых тегов аутентификации тегами указанной длины. Для chacha20-poly1305 опция authTagLength по умолчанию равна 16 байтам.

Алгоритм algorithm зависит от OpenSSL, примеры: aes192 и т. д. В последних выпусках OpenSSL опция openssl list -cipher-algorithms покажет доступные алгоритмы шифрования.

Ключ key - это необработанный ключ, используемый алгоритмом, а iv - это вектор инициализации. Оба аргумента должны быть строками в кодировке 'utf8, Buffers, TypedArray или DataView. Ключ может быть KeyObject типа secret. Если шифру не требуется вектор инициализации, iv может быть null.

При передаче строк для key или iv, пожалуйста, учитывайте предостережения при использовании строк в качестве входов в криптографические API.

Векторы инициализации должны быть непредсказуемыми и уникальными; в идеале они должны быть криптографически случайными. Они не обязательно должны быть секретными: IV обычно просто добавляются к шифротекстовым сообщениям в незашифрованном виде. Может показаться противоречивым, что что-то должно быть непредсказуемым и уникальным, но не должно быть секретным; помните, что атакующий не должен иметь возможности заранее предсказать, каким будет данный IV.

crypto.createDiffieHellman(prime[, primeEncoding][, generator][, generatorEncoding])

  • prime {string|ArrayBuffer|Buffer|TypedArray|DataView}
  • primeEncoding <string> кодировка строки prime.
  • generator {number|string|ArrayBuffer|Buffer|TypedArray|DataView} По умолчанию: 2.
  • generatorEncoding <string> кодировка строки генератора.
  • Возвращает: {DiffieHellman}

Создает объект обмена ключами DiffieHellman, используя предоставленный prime и необязательный определенный генератор.

Аргумент generator может быть числом, строкой или Buffer. Если generator не указан, используется значение 2.

Если указано primeEncoding, ожидается, что prime будет строкой, в противном случае ожидается Buffer, TypedArray или DataView.

Если указано generatorEncoding, ожидается, что generator будет строкой; в противном случае ожидается число, Buffer, TypedArray или DataView.

crypto.createDiffieHellman(primeLength[, generator])

  • primeLength <number>
  • генератор <number> По умолчанию: 2
  • Возвращает: {DiffieHellman}

Создает объект обмена ключами DiffieHellman и генерирует прайм из битов primeLength, используя необязательный конкретный числовой generator. Если generator не указан, используется значение 2.

crypto.createDiffieHellmanGroup(name)

  • name <string>
  • Возвращает: {DiffieHellmanGroup}

Псевдоним для crypto.getDiffieHellman()

crypto.createECDH(curveName)

  • curveName <string>
  • Возвращает: {ECDH}

Создает объект обмена ключами Elliptic Curve Diffie-Hellman (ECDH), используя предопределенную кривую, заданную строкой curveName. Используйте crypto.getCurves() для получения списка доступных имен кривых. В последних выпусках OpenSSL, openssl ecparam -list_curves также отобразит имя и описание каждой доступной эллиптической кривой.

crypto.createHash(algorithm[, options])

Создает и возвращает объект Hash, который может быть использован для генерации хэш-дайджестов с помощью заданного алгоритма. Необязательный аргумент options управляет поведением потока. Для хэш-функций XOF, таких как 'shake256', опция outputLength может быть использована для указания желаемой длины выходного потока в байтах.

Параметр algorithm зависит от доступных алгоритмов, поддерживаемых версией OpenSSL на данной платформе. Примерами являются sha256, sha512 и т. д. В последних выпусках OpenSSL команда openssl list -digest-algorithms отобразит доступные алгоритмы дайджеста.

Пример: генерация суммы sha256 для файла

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
import { createReadStream } from 'node:fs';
import { argv } from 'node:process';
const { createHash } = await import('node:crypto');

const filename = argv[2];

const hash = createHash('sha256');

const input = createReadStream(filename);
input.on('readable', () => {
    // Only one element is going to be produced by the
    // hash stream.
    const data = input.read();
    if (data) hash.update(data);
    else {
        console.log(`${hash.digest('hex')} ${filename}`);
    }
});
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
const { createReadStream } = require('node:fs');
const { createHash } = require('node:crypto');
const { argv } = require('node:process');

const filename = argv[2];

const hash = createHash('sha256');

const input = createReadStream(filename);
input.on('readable', () => {
    // Only one element is going to be produced by the
    // hash stream.
    const data = input.read();
    if (data) hash.update(data);
    else {
        console.log(`${hash.digest('hex')} ${filename}`);
    }
});

crypto.createHmac(algorithm, key[, options])

  • алгоритм <string>
  • key {string|ArrayBuffer|Buffer|TypedArray|DataView|KeyObject|CryptoKey}
  • options <Object> stream.transform options
    • encoding <string> Строковая кодировка, которую следует использовать, когда ключ является строкой.
  • Возвращает: {Hmac}

Создает и возвращает объект Hmac, который использует заданный алгоритм и ключ. Необязательный аргумент options управляет поведением потока.

Алгоритм зависит от доступных алгоритмов, поддерживаемых версией OpenSSL на данной платформе. Примеры: 'sha256', 'sha512' и т. д. В последних версиях OpenSSL, openssl list -digest-algorithms отобразит доступные алгоритмы дайджеста.

Ключ - это ключ HMAC, используемый для генерации криптографического хэша HMAC. Если это KeyObject, его тип должен быть secret.

Пример: генерация sha256 HMAC файла

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
import { createReadStream } from 'node:fs';
import { argv } from 'node:process';
const { createHmac } = await import('node:crypto');

const filename = argv[2];

const hmac = createHmac('sha256', 'a secret');

const input = createReadStream(filename);
input.on('readable', () => {
    // Only one element is going to be produced by the
    // hash stream.
    const data = input.read();
    if (data) hmac.update(data);
    else {
        console.log(`${hmac.digest('hex')} ${filename}`);
    }
});
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
const { createReadStream } = require('node:fs');
const { createHmac } = require('node:crypto');
const { argv } = require('node:process');

const filename = argv[2];

const hmac = createHmac('sha256', 'a secret');

const input = createReadStream(filename);
input.on('readable', () => {
    // Only one element is going to be produced by the
    // hash stream.
    const data = input.read();
    if (data) hmac.update(data);
    else {
        console.log(`${hmac.digest('hex')} ${filename}`);
    }
});

crypto.createPrivateKey(key)

  • key {Object|string|ArrayBuffer|Buffer|TypedArray|DataView}
    • key: {string|ArrayBuffer|Buffer|TypedArray|DataView|Object} Материал ключа, либо в формате PEM, DER, либо JWK.
    • формат: <string>. Должен быть pem, der или jwk. По умолчанию: 'pem'.
    • type: <string>. Должно быть 'pkcs1', 'pkcs8' или 'sec1'. Этот параметр требуется, только если формат - 'der' и игнорируется в противном случае.
    • passphrase: {строка | буфер}. Парольная фраза, которую следует использовать для расшифровки.
    • encoding: <string> Строковая кодировка, которую следует использовать, когда ключ является строкой.
  • Возвращает: {KeyObject}

Создает и возвращает новый объект ключа, содержащий закрытый ключ. Если key является строкой или Buffer, format принимается равным 'pem'; в противном случае key должен быть объектом со свойствами, описанными выше.

Если закрытый ключ зашифрован, необходимо указать пассфразу. Длина парольной фразы ограничена 1024 байтами.

crypto.createPublicKey(key)

  • key {Object|string|ArrayBuffer|Buffer|TypedArray|DataView}
    • key: {string|ArrayBuffer|Buffer|TypedArray|DataView|Object} Материал ключа, либо в формате PEM, DER, либо JWK.
    • формат: <string>. Должен быть 'pem, 'der или 'jwk. По умолчанию: 'pem'.
    • type: <string>. Должно быть 'pkcs1' или 'spki'. Этот параметр требуется только если формат - 'der' и игнорируется в противном случае.
    • encoding <string> Строковая кодировка, которую следует использовать, когда ключ является строкой.
  • Возвращает: {KeyObject}

Создает и возвращает новый объект ключа, содержащий открытый ключ. Если key - строка или Buffer, формат принимается равным 'pem'; если key - KeyObject с типом 'private', открытый ключ будет получен из данного закрытого ключа; в противном случае key должен быть объектом со свойствами, описанными выше.

Если формат pem, то ключ может также быть сертификатом X.509.

Поскольку открытые ключи могут быть получены из закрытых ключей, вместо открытого ключа может быть передан закрытый ключ. В этом случае эта функция ведет себя так же, как если бы была вызвана crypto.createPrivateKey(), за исключением того, что тип возвращаемого KeyObject будет 'public' и что закрытый ключ не может быть извлечен из возвращаемого KeyObject. Аналогично, если передан KeyObject с типом 'private', будет возвращен новый KeyObject с типом 'public' и невозможно будет извлечь закрытый ключ из возвращенного объекта.

crypto.createSecretKey(key[, encoding])

  • key {string|ArrayBuffer|Buffer|TypedArray|DataView}
  • encoding <string> Кодировка строки, когда ключ является строкой.
  • Возвращает: {KeyObject}

Создает и возвращает новый объект key, содержащий секретный ключ для симметричного шифрования или Hmac.

crypto.createSign(algorithm[, options])

Создает и возвращает объект Sign, использующий заданный алгоритм. Используйте crypto.getHashes() для получения имен доступных алгоритмов дайджеста. Необязательный аргумент options управляет поведением stream.Writable.

В некоторых случаях экземпляр Sign может быть создан с использованием имени алгоритма подписи, например 'RSA-SHA256', вместо алгоритма дайджеста. В этом случае будет использоваться соответствующий алгоритм подписи. Это работает не для всех алгоритмов подписи, например, 'ecdsa-with-SHA256', поэтому лучше всегда использовать имена алгоритмов дайджеста.

crypto.createVerify(algorithm[, options])

Создает и возвращает объект Verify, использующий заданный алгоритм. Используйте crypto.getHashes() для получения массива имен доступных алгоритмов подписания. Необязательный аргумент options управляет поведением stream.Writable.

В некоторых случаях экземпляр Verify может быть создан с использованием имени алгоритма подписи, например 'RSA-SHA256', вместо алгоритма дайджеста. В этом случае будет использоваться соответствующий алгоритм. Это работает не для всех алгоритмов подписи, например, 'ecdsa-with-SHA256', поэтому лучше всегда использовать имена алгоритмов дайджеста.

crypto.diffieHellman(options)

  • options: <Object>
    • privateKey: {KeyObject}
    • publicKey: {KeyObject}
  • Возвращает: <Buffer>

Вычисляет секрет Диффи-Хеллмана на основе privateKey и publicKey. Оба ключа должны иметь одинаковый asymmetricKeyType, который должен быть одним из 'dh' (для Diffie-Hellman), 'ec' (для ECDH), 'x448' или 'x25519' (для ECDH-ES).

crypto.generateKey(type, options, callback)

  • type: <string>. Предполагаемое использование сгенерированного секретного ключа. В настоящее время принимаются значения 'hmac' и 'aes'.
    • options: <Object>
      • length: <number> Длина бита генерируемого ключа. Это должно быть значение больше 0.
        • Если type имеет значение 'hmac', минимальная длина равна 8, а максимальная - 231-1. Если значение не кратно 8, сгенерированный ключ будет усечен до Math.floor(length / 8).
        • Если type - 'aes, длина должна быть одной из 128, 192 или 256.
    • callback: <Function>

Асинхронно генерирует новый случайный секретный ключ заданной длины. Тип type определяет, какие проверки будут выполняться для длины.

1
2
3
4
5
6
const { generateKey } = await import('node:crypto');

generateKey('hmac', { length: 64 }, (err, key) => {
    if (err) throw err;
    console.log(key.export().toString('hex')); // 46e..........620
});
1
2
3
4
5
6
const { generateKey } = require('node:crypto');

generateKey('hmac', { length: 64 }, (err, key) => {
    if (err) throw err;
    console.log(key.export().toString('hex')); // 46e..........620
});

crypto.generateKeyPair(type, options, callback).

  • type: <string>. Должно быть rsa, rsa-pss, dsa, ec, ed25519, ed448, x25519, x448 или dh.
  • options: <Object>
    • modulusLength: <number> Размер ключа в битах (RSA, DSA).
    • publicExponent: <number> Публичная экспонента (RSA). По умолчанию: 0x10001.
    • hashAlgorithm: <string> Имя дайджеста сообщения (RSA-PSS).
    • mgf1HashAlgorithm: <string> Имя дайджеста сообщения, используемого MGF1 (RSA-PSS).
    • saltLength: <number> Минимальная длина соли в байтах (RSA-PSS).
    • divisorLength: <number> Размер q в битах (DSA).
    • namedCurve: <string> Имя кривой, которую следует использовать (EC).
    • prime: <Buffer> Параметр prime (DH).
    • primeLength: <number> Длина прайма в битах (DH).
    • generator: <number> Пользовательский генератор (DH). По умолчанию: 2.
    • groupName: <string> Имя группы Диффи-Хеллмана (DH). См. crypto.getDiffieHellman().
    • paramEncoding: <string>. Должно быть именованным или явным (EC). По умолчанию: 'named'.
    • publicKeyEncoding: <Object> См. keyObject.export().
    • privateKeyEncoding: <Object> См. keyObject.export().
  • callback: <Function>
    • err: <Error>
    • publicKey: {string | Buffer | KeyObject}
    • privateKey: {string | Buffer | KeyObject}.

Генерирует новую пару асимметричных ключей заданного типа. В настоящее время поддерживаются RSA, RSA-PSS, DSA, EC, Ed25519, Ed448, X25519, X448 и DH.

Если было указано publicKeyEncoding или privateKeyEncoding, эта функция ведет себя так, как если бы для ее результата был вызван keyObject.export(). В противном случае соответствующая часть ключа возвращается как KeyObject.

Рекомендуется кодировать открытые ключи как 'spki' и закрытые ключи как 'pkcs8' с шифрованием для длительного хранения:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
const { generateKeyPair } = await import('node:crypto');

generateKeyPair(
    'rsa',
    {
        modulusLength: 4096,
        publicKeyEncoding: {
            type: 'spki',
            format: 'pem',
        },
        privateKeyEncoding: {
            type: 'pkcs8',
            format: 'pem',
            cipher: 'aes-256-cbc',
            passphrase: 'top secret',
        },
    },
    (err, publicKey, privateKey) => {
        // Handle errors and use the generated key pair.
    }
);
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
const { generateKeyPair } = require('node:crypto');

generateKeyPair(
    'rsa',
    {
        modulusLength: 4096,
        publicKeyEncoding: {
            type: 'spki',
            format: 'pem',
        },
        privateKeyEncoding: {
            type: 'pkcs8',
            format: 'pem',
            cipher: 'aes-256-cbc',
            passphrase: 'top secret',
        },
    },
    (err, publicKey, privateKey) => {
        // Handle errors and use the generated key pair.
    }
);

По завершении будет вызван callback с err, установленным в undefined и publicKey / privateKey, представляющими сгенерированную пару ключей.

Если этот метод вызывается как его util.promisify() версия, он возвращает Promise для Object со свойствами publicKey и privateKey.

crypto.generateKeyPairSync(type, options)

  • type: <string>. Должно быть 'rsa, 'rsa-pss, 'dsa, 'ec, 'ed25519, 'ed448, 'x25519, 'x448 или 'dh.
  • options: <Object>
    • modulusLength: <number> Размер ключа в битах (RSA, DSA).
    • publicExponent: <number> Публичная экспонента (RSA). По умолчанию: 0x10001.
    • hashAlgorithm: <string> Имя дайджеста сообщения (RSA-PSS).
    • mgf1HashAlgorithm: <string> Имя дайджеста сообщения, используемого MGF1 (RSA-PSS).
    • saltLength: <number> Минимальная длина соли в байтах (RSA-PSS).
    • divisorLength: <number> Размер q в битах (DSA).
    • namedCurve: <string> Имя кривой, которую следует использовать (EC).
    • prime: <Buffer> Параметр prime (DH).
    • primeLength: <number> Длина прайма в битах (DH).
    • generator: <number> Пользовательский генератор (DH). По умолчанию: 2.
    • groupName: <string> Имя группы Диффи-Хеллмана (DH). См. crypto.getDiffieHellman().
    • paramEncoding: <string>. Должно быть именованным или явным (EC). По умолчанию: 'named'.
    • publicKeyEncoding: <Object> См. keyObject.export().
    • privateKeyEncoding: <Object> См. keyObject.export().
  • Возвращает: <Object>
    • publicKey: {string | Buffer | KeyObject}
    • privateKey: {string | Buffer | KeyObject}.

Генерирует новую пару асимметричных ключей заданного типа. В настоящее время поддерживаются RSA, RSA-PSS, DSA, EC, Ed25519, Ed448, X25519, X448 и DH.

Если было указано publicKeyEncoding или privateKeyEncoding, эта функция ведет себя так, как если бы для ее результата был вызван keyObject.export(). В противном случае соответствующая часть ключа возвращается как KeyObject.

При кодировании открытых ключей рекомендуется использовать 'spki'. При кодировании закрытых ключей рекомендуется использовать 'pkcs8' с сильной парольной фразой и хранить парольную фразу в тайне.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
const { generateKeyPairSync } = await import('node:crypto');

const { publicKey, privateKey } = generateKeyPairSync(
    'rsa',
    {
        modulusLength: 4096,
        publicKeyEncoding: {
            type: 'spki',
            format: 'pem',
        },
        privateKeyEncoding: {
            type: 'pkcs8',
            format: 'pem',
            cipher: 'aes-256-cbc',
            passphrase: 'top secret',
        },
    }
);
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
const { generateKeyPairSync } = require('node:crypto');

const { publicKey, privateKey } = generateKeyPairSync(
    'rsa',
    {
        modulusLength: 4096,
        publicKeyEncoding: {
            type: 'spki',
            format: 'pem',
        },
        privateKeyEncoding: {
            type: 'pkcs8',
            format: 'pem',
            cipher: 'aes-256-cbc',
            passphrase: 'top secret',
        },
    }
);

Возвращаемое значение { publicKey, privateKey } представляет собой сгенерированную пару ключей. Если выбрана кодировка PEM, то соответствующий ключ будет строкой, в противном случае это будет буфер, содержащий данные, закодированные в формате DER.

crypto.generateKeySync(type, options)

  • type: <string>. Предполагаемое использование сгенерированного секретного ключа. В настоящее время принимаются значения 'hmac' и 'aes'.
    • options: <Object>
      • length: <number> Длина бита генерируемого ключа.
        • Если type - 'hmac', минимальная длина равна 8, а максимальная - 231-1. Если значение не кратно 8, сгенерированный ключ будет усечен до Math.floor(length / 8).
        • Если type - aes, длина должна быть одной из 128, 192 или 256.
    • Возвращает: {KeyObject}

Синхронно генерирует новый случайный секретный ключ заданной длины. Тип type определяет, какие проверки будут выполняться для длины.

1
2
3
4
const { generateKeySync } = await import('node:crypto');

const key = generateKeySync('hmac', { length: 64 });
console.log(key.export().toString('hex')); // e89..........41e
1
2
3
4
const { generateKeySync } = require('node:crypto');

const key = generateKeySync('hmac', { length: 64 });
console.log(key.export().toString('hex')); // e89..........41e

crypto.generatePrime(size[, options[, callback]])

  • size <number> Размер (в битах) простого числа для генерации.
  • options <Object>
    • add {ArrayBuffer|SharedArrayBuffer|TypedArray|Buffer|DataView|bigint}
    • rem {ArrayBuffer|SharedArrayBuffer|TypedArray|Buffer|DataView|bigint}
    • safe <boolean> По умолчанию: false.
    • bigint <boolean> Если true, сгенерированный прайм возвращается в виде bigint.
  • callback <Function>
    • err <Error>
    • prime {ArrayBuffer|bigint}

Генерирует псевдослучайное простое число размером size бит.

Если options.safe равно true, то прайм будет безопасным праймом - то есть (прайм - 1) / 2 также будет праймом.

Параметры options.add и options.rem могут быть использованы для обеспечения дополнительных требований, например, для Диффи-Хеллмана:

  • Если options.add и options.rem оба заданы, то прайм будет удовлетворять условию, что prime % add = rem.
  • Если установлено только options.add и options.safe не true, то прайм будет удовлетворять условию, что prime % add = 1.
  • Если задано только options.add и options.safe имеет значение true, то вместо этого прайм будет удовлетворять условию, что prime % add = 3. Это необходимо, поскольку prime % add = 1 для options.add > 2 противоречит условию, навязанному options.safe.
  • options.rem игнорируется, если options.add не указан.

И options.add, и options.rem должны быть закодированы как big-endian последовательности, если они заданы как ArrayBuffer, SharedArrayBuffer, TypedArray, Buffer или DataView.

По умолчанию прайм кодируется как big-endian последовательность октетов в <ArrayBuffer>. Если опция bigint имеет значение true, то предоставляется <bigint>.

crypto.generatePrimeSync(size[, options])

  • size <number> Размер (в битах) генерируемого прайма.
  • options <Object>
    • add {ArrayBuffer|SharedArrayBuffer|TypedArray|Buffer|DataView|bigint}
    • rem {ArrayBuffer|SharedArrayBuffer|TypedArray|Buffer|DataView|bigint}
    • safe <boolean> По умолчанию: false.
    • bigint <boolean> Если true, сгенерированный прайм возвращается в виде bigint.
  • Возвращает: {ArrayBuffer|bigint}

Генерирует псевдослучайное простое число размером size бит.

Если options.safe равно true, то прайм будет безопасным праймом - то есть, (прайм - 1) / 2 также будет праймом.

Параметры options.add и options.rem могут быть использованы для обеспечения дополнительных требований, например, для Диффи-Хеллмана:

  • Если options.add и options.rem оба заданы, то прайм будет удовлетворять условию, что prime % add = rem.
  • Если установлено только options.add и options.safe не true, то прайм будет удовлетворять условию, что prime % add = 1.
  • Если задано только options.add и options.safe имеет значение true, то вместо этого прайм будет удовлетворять условию, что prime % add = 3. Это необходимо, поскольку prime % add = 1 для options.add > 2 противоречит условию, навязанному options.safe.
  • options.rem игнорируется, если options.add не указан.

И options.add, и options.rem должны быть закодированы как big-endian последовательности, если они заданы как ArrayBuffer, SharedArrayBuffer, TypedArray, Buffer или DataView.

По умолчанию прайм кодируется как big-endian последовательность октетов в <ArrayBuffer>. Если опция bigint имеет значение true, то предоставляется <bigint>.

crypto.getCipherInfo(nameOrNid[, options])

  • nameOrNid: {string|number} Имя или nid шифра для запроса.
  • options: <Object>
    • keyLength: <number> Длина тестового ключа.
    • ivLength: <number> Тестовая длина IV.
  • Возвращает: <Object>
    • name <string> Имя шифра
    • nid <number> nid шифра
    • blockSize <number> Размер блока шифра в байтах. Это свойство опускается, если mode имеет значение 'stream'.
    • ivLength <number> Ожидаемая или стандартная длина вектора инициализации в байтах. Это свойство опускается, если шифр не использует вектор инициализации.
    • keyLength <number> Ожидаемая длина ключа или длина ключа по умолчанию в байтах.
    • mode <string> Режим шифра. Один из 'cbc', 'ccm', 'cfb', 'ctr', 'ecb', 'gcm', 'ocb', 'ofb', 'stream', 'wrap', 'xts'.

Возвращает информацию о заданном шифре.

Некоторые шифры принимают ключи переменной длины и векторы инициализации. По умолчанию метод crypto.getCipherInfo() возвращает значения по умолчанию для этих шифров. Чтобы проверить, приемлема ли заданная длина ключа или длина iv для данного шифра, используйте опции keyLength и ivLength. Если заданные значения неприемлемы, будет возвращено значение undefined.

crypto.getCiphers()

  • Возвращает: <string[]> Массив с именами поддерживаемых алгоритмов шифрования.
1
2
3
const { getCiphers } = await import('node:crypto');

console.log(getCiphers()); // ['aes-128-cbc', 'aes-128-ccm', ...]
1
2
3
const { getCiphers } = require('node:crypto');

console.log(getCiphers()); // ['aes-128-cbc', 'aes-128-ccm', ...]

crypto.getCurves()

  • Возвращает: <string[]> Массив с именами поддерживаемых эллиптических кривых.
1
2
3
const { getCurves } = await import('node:crypto');

console.log(getCurves()); // ['Oakley-EC2N-3', 'Oakley-EC2N-4', ...]
1
2
3
const { getCurves } = require('node:crypto');

console.log(getCurves()); // ['Oakley-EC2N-3', 'Oakley-EC2N-4', ...]

crypto.getDiffieHellman(groupName)

  • groupName <string>
  • Возвращает: {DiffieHellmanGroup}

Создает предопределенный объект обмена ключами DiffieHellmanGroup. Поддерживаемые группы перечислены в документации по DiffieHellmanGroup.

Возвращаемый объект имитирует интерфейс объектов, создаваемых crypto.createDiffieHellman(), но не позволяет изменять ключи (например, с помощью diffieHellman.setPublicKey()). Преимущество использования этого метода в том, что сторонам не нужно предварительно генерировать групповой модуль и обмениваться им, что экономит процессорное и коммуникационное время.

Пример (получение общего секрета):

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
const { getDiffieHellman } = await import('node:crypto');
const alice = getDiffieHellman('modp14');
const bob = getDiffieHellman('modp14');

alice.generateKeys();
bob.generateKeys();

const aliceSecret = alice.computeSecret(
    bob.getPublicKey(),
    null,
    'hex'
);
const bobSecret = bob.computeSecret(
    alice.getPublicKey(),
    null,
    'hex'
);

/* aliceSecret и bobSecret должны быть одинаковыми */
console.log(aliceSecret === bobSecret);
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
const { getDiffieHellman } = require('node:crypto');

const alice = getDiffieHellman('modp14');
const bob = getDiffieHellman('modp14');

alice.generateKeys();
bob.generateKeys();

const aliceSecret = alice.computeSecret(
    bob.getPublicKey(),
    null,
    'hex'
);
const bobSecret = bob.computeSecret(
    alice.getPublicKey(),
    null,
    'hex'
);

/* aliceSecret и bobSecret должны быть одинаковыми */
console.log(aliceSecret === bobSecret);

crypto.getFips()

  • Возвращает: <number> 1, если и только если в настоящее время используется FIPS-совместимый криптопровайдер, 0 в противном случае. В будущем выпуске semver-major тип возврата этого API может быть изменен на <boolean>.

crypto.getHashes()

  • Возвращает: <string[]> Массив имен поддерживаемых алгоритмов хэширования, например, 'RSA-SHA256'. Хеш-алгоритмы также называют алгоритмами "дайджеста".
1
2
3
const { getHashes } = await import('node:crypto');

console.log(getHashes()); // ['DSA', 'DSA-SHA', 'DSA-SHA1', ...]
1
2
3
const { getHashes } = require('node:crypto');

console.log(getHashes()); // ['DSA', 'DSA-SHA', 'DSA-SHA1', ...]

crypto.getRandomValues(typedArray)

  • typedArray {Buffer|TypedArray|DataView|ArrayBuffer}
  • Возвращает: {Buffer|TypedArray|DataView|ArrayBuffer} Возвращает typedArray.

Удобный псевдоним для crypto.webcrypto.getRandomValues(). Эта реализация не соответствует спецификации Web Crypto, для написания веб-совместимого кода используйте crypto.webcrypto.getRandomValues().

crypto.hkdf(digest, ikm, salt, info, keylen, callback)

  • digest <string> Используемый алгоритм дайджеста.
  • ikm {string|ArrayBuffer|Buffer|TypedArray|DataView|KeyObject} Входной ключевой материал. Должен быть указан, но может иметь нулевую длину.
  • salt {string|ArrayBuffer|Buffer|TypedArray|DataView} Значение соли. Должно быть указано, но может иметь нулевую длину.
  • info {string|ArrayBuffer|Buffer|TypedArray|DataView} Дополнительное информационное значение. Должно быть указано, но может иметь нулевую длину и не может быть больше 1024 байт.
  • keylen <number> Длина генерируемого ключа. Должна быть больше 0. Максимально допустимое значение равно 255, умноженное на количество байт, выдаваемых выбранной функцией дайджеста (например, sha512 генерирует 64-байтовые хэши, что делает максимальный выход HKDF 16320 байт).
  • callback <Function>

HKDF - это простая функция выведения ключей, определенная в RFC 5869. Заданные ikm, salt и info используются вместе с digest для получения ключа длиной keylen байт.

Поставленная функция callback вызывается с двумя аргументами: err и derivedKey. Если при выведении ключа произошла ошибка, будет установлено значение err, в противном случае err будет равно null. Успешно сгенерированный derivedKey будет передан в обратный вызов как <ArrayBuffer>. Если какой-либо из входных аргументов содержит недопустимые значения или типы, будет выдана ошибка.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
import { Buffer } from 'node:buffer';
const { hkdf } = await import('node:crypto');

hkdf(
    'sha512',
    'key',
    'salt',
    'info',
    64,
    (err, derivedKey) => {
        if (err) throw err;
        console.log(
            Buffer.from(derivedKey).toString('hex')
        ); // '24156e2...5391653'
    }
);
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
const { hkdf } = require('node:crypto');
const { Buffer } = require('node:buffer');

hkdf(
    'sha512',
    'key',
    'salt',
    'info',
    64,
    (err, derivedKey) => {
        if (err) throw err;
        console.log(
            Buffer.from(derivedKey).toString('hex')
        ); // '24156e2...5391653'
    }
);

crypto.hkdfSync(digest, ikm, salt, info, keylen)

  • digest <string> Используемый алгоритм дайджеста.
  • ikm {string|ArrayBuffer|Buffer|TypedArray|DataView|KeyObject} Входной ключевой материал. Должен быть указан, но может иметь нулевую длину.
  • salt {string|ArrayBuffer|Buffer|TypedArray|DataView} Значение соли. Должно быть указано, но может иметь нулевую длину.
  • info {string|ArrayBuffer|Buffer|TypedArray|DataView} Дополнительное информационное значение. Должно быть указано, но может иметь нулевую длину и не может быть больше 1024 байт.
  • keylen <number> Длина генерируемого ключа. Должна быть больше 0. Максимально допустимое значение равно 255, умноженное на количество байт, генерируемых выбранной функцией дайджеста (например, sha512 генерирует 64-байтовые хэши, что делает максимальный выход HKDF 16320 байт).
  • Возвращает: <ArrayBuffer>.

Предоставляет синхронную функцию выведения ключей HKDF, как определено в RFC 5869. Заданные ikm, salt и info используются вместе с digest для получения ключа длиной keylen байт.

Успешно сгенерированный derivedKey будет возвращен в виде <ArrayBuffer>.

Если в качестве входных аргументов указаны недопустимые значения или типы, или если производный ключ не может быть сгенерирован, будет выдана ошибка.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
import { Buffer } from 'node:buffer';
const { hkdfSync } = await import('node:crypto');

const derivedKey = hkdfSync(
    'sha512',
    'key',
    'salt',
    'info',
    64
);
console.log(Buffer.from(derivedKey).toString('hex')); // '24156e2...5391653'
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
const { hkdfSync } = require('node:crypto');
const { Buffer } = require('node:buffer');

const derivedKey = hkdfSync(
    'sha512',
    'key',
    'salt',
    'info',
    64
);
console.log(Buffer.from(derivedKey).toString('hex')); // '24156e2...5391653'

crypto.pbkdf2(password, salt, iterations, keylen, digest, callback)

  • password {string|ArrayBuffer|Buffer|TypedArray|DataView}
  • соль {string|ArrayBuffer|Buffer|TypedArray|DataView}
  • iterations <number>
  • keylen <number>
  • digest <string>
  • callback <Function>
    • err {ошибка}
    • derivedKey <Buffer>

Обеспечивает асинхронную реализацию Password-Based Key Derivation Function 2 (PBKDF2). Выбранный алгоритм дайджеста HMAC, указанный в digest, применяется для получения ключа требуемой длины байта (keylen) из password, alt и iterations.

Поставленная функция callback вызывается с двумя аргументами: err и derivedKey. Если при создании ключа произошла ошибка, то err будет установлен; в противном случае err будет равен null. По умолчанию успешно сгенерированный derivedKey будет передан обратному вызову как Buffer. Если в любом из входных аргументов указаны недопустимые значения или типы, будет выдана ошибка.

Аргумент iterations должен быть числом, установленным как можно выше. Чем больше число итераций, тем надежнее будет производный ключ, но на выполнение потребуется больше времени.

Соль" должна быть настолько уникальной, насколько это возможно. Рекомендуется, чтобы соль была случайной и имела длину не менее 16 байт. Подробности см. в NIST SP 800-132.

При передаче строк для password или salt, пожалуйста, учитывайте предостережения при использовании строк в качестве входных данных для криптографических API.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
const { pbkdf2 } = await import('node:crypto');

pbkdf2(
    'secret',
    'salt',
    100000,
    64,
    'sha512',
    (err, derivedKey) => {
        if (err) throw err;
        console.log(derivedKey.toString('hex')); // '3745e48...08d59ae'
    }
);
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
const { pbkdf2 } = require('node:crypto');

pbkdf2(
    'secret',
    'salt',
    100000,
    64,
    'sha512',
    (err, derivedKey) => {
        if (err) throw err;
        console.log(derivedKey.toString('hex')); // '3745e48...08d59ae'
    }
);

Свойство crypto.DEFAULT_ENCODING можно использовать для изменения способа передачи derivedKey в обратный вызов. Однако это свойство было устаревшим, и его использования следует избегать.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
import crypto from 'node:crypto';
crypto.DEFAULT_ENCODING = 'hex';
crypto.pbkdf2(
    'secret',
    'salt',
    100000,
    512,
    'sha512',
    (err, derivedKey) => {
        if (err) throw err;
        console.log(derivedKey); // '3745e48...aa39b34'
    }
);
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
const crypto = require('node:crypto');
crypto.DEFAULT_ENCODING = 'hex';
crypto.pbkdf2(
    'secret',
    'salt',
    100000,
    512,
    'sha512',
    (err, derivedKey) => {
        if (err) throw err;
        console.log(derivedKey); // '3745e48...aa39b34'
    }
);

Массив поддерживаемых дайджест-функций можно получить с помощью crypto.getHashes().

Этот API использует пул потоков libuv, что может иметь неожиданные и негативные последствия для производительности некоторых приложений; смотрите документацию UV_THREADPOOL_SIZE для получения дополнительной информации.

crypto.pbkdf2Sync(password, salt, iterations, keylen, digest)

Предоставляет синхронную реализацию Password-Based Key Derivation Function 2 (PBKDF2). Выбранный алгоритм дайджеста HMAC, указанный в digest, применяется для получения ключа запрашиваемой длины байта (keylen) из password, alt и iterations.

Если произойдет ошибка, будет выдано сообщение Error, в противном случае полученный ключ будет возвращен в виде буфера.

Аргумент iterations должен быть числом, установленным как можно выше. Чем больше число итераций, тем надежнее будет полученный ключ, но на это потребуется больше времени.

Соль" должна быть настолько уникальной, насколько это возможно. Рекомендуется, чтобы соль была случайной и имела длину не менее 16 байт. Подробности см. в NIST SP 800-132.

При передаче строк для password или salt, пожалуйста, учитывайте предостережения при использовании строк в качестве входных данных для криптографических API.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
const { pbkdf2Sync } = await import('node:crypto');

const key = pbkdf2Sync(
    'secret',
    'salt',
    100000,
    64,
    'sha512'
);
console.log(key.toString('hex')); // '3745e48...08d59ae'
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
const { pbkdf2Sync } = require('node:crypto');

const key = pbkdf2Sync(
    'secret',
    'salt',
    100000,
    64,
    'sha512'
);
console.log(key.toString('hex')); // '3745e48...08d59ae'

Свойство crypto.DEFAULT_ENCODING можно использовать для изменения способа возврата derivedKey. Однако это свойство устарело, и его использования следует избегать.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
import crypto from 'node:crypto';
crypto.DEFAULT_ENCODING = 'hex';
const key = crypto.pbkdf2Sync(
    'secret',
    'salt',
    100000,
    512,
    'sha512'
);
console.log(key); // '3745e48...aa39b34'
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
const crypto = require('node:crypto');
crypto.DEFAULT_ENCODING = 'hex';
const key = crypto.pbkdf2Sync(
    'secret',
    'salt',
    100000,
    512,
    'sha512'
);
console.log(key); // '3745e48...aa39b34'

Массив поддерживаемых функций дайджеста можно получить с помощью crypto.getHashes().

crypto.privateDecrypt(privateKey, buffer)

  • privateKey {Object|string|ArrayBuffer|Buffer|TypedArray|DataView|KeyObject|CryptoKey}
    • oaepHash <string> Хэш-функция, используемая для OAEP padding и MGF1. По умолчанию: 'sha1'.
    • oaepLabel {string|ArrayBuffer|Buffer|TypedArray|DataView} Метка, которую следует использовать для OAEP-подкладки. Если не указано, метка не используется.
    • padding {crypto.constants} Необязательное значение набивки, определенное в crypto.constants, которое может быть: crypto.constants.RSA_NO_PADDING, crypto.constants.RSA_PKCS1_PADDING или crypto.constants.RSA_PKCS1_OAEP_PADDING.
  • buffer {string|ArrayBuffer|Buffer|TypedArray|DataView}
  • Возвращает: <Buffer> Новый буфер с расшифрованным содержимым.

Расшифровывает buffer с помощью privateKey. Буфер был ранее зашифрован с помощью соответствующего открытого ключа, например, с помощью crypto.publicEncrypt().

Если privateKey не является KeyObject, эта функция ведет себя так, как если бы privateKey был передан в crypto.createPrivateKey(). Если это объект, может быть передано свойство padding. В противном случае эта функция использует RSA_PKCS1_OAEP_PADDING.

crypto.privateEncrypt(privateKey, buffer)

  • privateKey {Object|string|ArrayBuffer|Buffer|TypedArray|DataView|KeyObject|CryptoKey}
    • key {string|ArrayBuffer|Buffer|TypedArray|DataView|KeyObject|CryptoKey} Закрытый ключ в кодировке PEM.
    • passphrase {string|ArrayBuffer|Buffer|TypedArray|DataView} Необязательная ключевая фраза для закрытого ключа.
    • padding {crypto.constants} Необязательное значение прокладки, определенное в crypto.constants, которое может быть: crypto.constants.RSA_NO_PADDING или crypto.constants.RSA_PKCS1_PADDING.
    • encoding <string> Строковая кодировка, которую следует использовать, когда буфер, ключ или пассфраза являются строками.
  • buffer {string|ArrayBuffer|Buffer|TypedArray|DataView}
  • Возвращает: <Buffer> Новый буфер с зашифрованным содержимым.

Шифрует buffer с помощью privateKey. Возвращенные данные можно расшифровать с помощью соответствующего открытого ключа, например, используя crypto.publicDecrypt().

Если privateKey не является KeyObject, эта функция ведет себя так, как если бы privateKey был передан в crypto.createPrivateKey(). Если это объект, может быть передано свойство padding. В противном случае эта функция использует RSA_PKCS1_PADDING.

crypto.publicDecrypt(key, buffer)

  • ключ {Object|string|ArrayBuffer|Buffer|TypedArray|DataView|KeyObject|CryptoKey}
    • passphrase {string|ArrayBuffer|Buffer|TypedArray|DataView} Необязательная ключевая фраза для закрытого ключа.
    • padding {crypto.constants} Необязательное значение прокладки, определенное в crypto.constants, которое может быть: crypto.constants.RSA_NO_PADDING или crypto.constants.RSA_PKCS1_PADDING.
    • encoding <string> Строковая кодировка, которую следует использовать, когда буфер, ключ или пассфраза являются строками.
  • buffer {string|ArrayBuffer|Buffer|TypedArray|DataView}
  • Возвращает: <Buffer> Новый буфер с расшифрованным содержимым.

Расшифровывает buffer с помощью key.buffer был ранее зашифрован с помощью соответствующего закрытого ключа, например, с помощью crypto.privateEncrypt().

Если key не является KeyObject, эта функция ведет себя так, как если бы key был передан в crypto.createPublicKey(). Если это объект, может быть передано свойство padding. В противном случае эта функция использует RSA_PKCS1_PADDING.

Поскольку открытые ключи RSA могут быть получены из закрытых ключей, вместо открытого ключа может быть передан закрытый ключ.

crypto.publicEncrypt(key, buffer)

  • key {Object|string|ArrayBuffer|Buffer|TypedArray|DataView|KeyObject|CryptoKey}
    • ключ {string|ArrayBuffer|Buffer|TypedArray|DataView|KeyObject|CryptoKey} Открытый или закрытый ключ в кодировке PEM, {KeyObject} или {CryptoKey}.
    • oaepHash <string> Хэш-функция, используемая для OAEP padding и MGF1. По умолчанию: 'sha1'.
    • oaepLabel {string|ArrayBuffer|Buffer|TypedArray|DataView} Метка, которую следует использовать для OAEP-подкладки. Если не указано, метка не используется.
    • passphrase {string|ArrayBuffer|Buffer|TypedArray|DataView} Необязательная ключевая фраза для закрытого ключа.
    • padding {crypto.constants} Необязательное значение прокладки, определенное в crypto.constants, которое может быть: crypto.constants.RSA_NO_PADDING, crypto.constants.RSA_PKCS1_PADDING или crypto.constants.RSA_PKCS1_OAEP_PADDING.
    • encoding <string> Строковая кодировка, которую следует использовать, когда буфер, ключ, oaepLabel или passphrase являются строками.
  • buffer {string|ArrayBuffer|Buffer|TypedArray|DataView}
  • Возвращает: <Buffer> Новый буфер с зашифрованным содержимым.

Шифрует содержимое buffer с помощью key и возвращает новый Buffer с зашифрованным содержимым. Возвращенные данные можно расшифровать с помощью соответствующего закрытого ключа, например, используя crypto.privateDecrypt().

Если key не является KeyObject, эта функция ведет себя так, как если бы key был передан в crypto.createPublicKey(). Если это объект, может быть передано свойство padding. В противном случае эта функция использует RSA_PKCS1_OAEP_PADDING.

Поскольку открытые ключи RSA могут быть получены из закрытых ключей, вместо открытого ключа может быть передан закрытый ключ.

crypto.randomBytes(size[, callback])

  • size <number> Количество байт для генерации. size не должно быть больше, чем 2**31 - 1.
  • callback <Function>
  • Возвращает: <Buffer>, если функция callback не предоставлена.

Генерирует криптографически сильные псевдослучайные данные. Аргумент size представляет собой число, указывающее количество байт для генерации.

Если указана функция callback, байты генерируются асинхронно, а функция callback вызывается с двумя аргументами: err и buf. Если произошла ошибка, то err будет объектом Error, в противном случае - null. Аргумент buf представляет собой буфер, содержащий сгенерированные байты.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
// Асинхронный
const { randomBytes } = await import('node:crypto');

randomBytes(256, (err, buf) => {
    if (err) throw err;
    console.log(
        `${
            buf.length
        } байт случайных данных: ${buf.toString('hex')}`
    );
});
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
// Асинхронный
const { randomBytes } = require('node:crypto');

randomBytes(256, (err, buf) => {
    if (err) throw err;
    console.log(
        `${
            buf.length
        } байт случайных данных: ${buf.toString('hex')}`
    );
});

Если функция callback не указана, случайные байты генерируются синхронно и возвращаются в виде буфера. При возникновении проблем с генерацией байтов будет выдана ошибка.

1
2
3
4
5
6
7
8
9
// Синхронный
const {
  randomBytes,
} = await import('node:crypto');


const buf = randomBytes(256);
console.log(
  ``${buf.length} байт случайных данных: ${buf.toString('hex')}``);
1
2
3
4
5
6
7
8
9
// Синхронный
const {
  randomBytes,
} = require('node:crypto');


const buf = randomBytes(256);
console.log(
  ``${buf.length} байт случайных данных: ${buf.toString('hex')}``);

Метод crypto.randomBytes() не завершится, пока не будет получено достаточное количество энтропии. Обычно это не должно занимать более нескольких миллисекунд. Единственное время, когда генерация случайных байтов может блокироваться на более длительный период времени, это сразу после загрузки, когда вся система еще не имеет достаточного количества энтропии.

Этот API использует пул потоков libuv, что может иметь неожиданные и негативные последствия для производительности некоторых приложений; смотрите документацию UV_THREADPOOL_SIZE для получения дополнительной информации.

Асинхронная версия crypto.randomBytes() выполняется за один запрос к пулу потоков. Чтобы минимизировать изменение длины задачи пула потоков, разделяйте большие запросы randomBytes, когда это делается в рамках выполнения запроса клиента.

crypto.randomFillSync(buffer[, offset][, size])

  • buffer {ArrayBuffer|Buffer|TypedArray|DataView} Должен быть предоставлен. Размер предоставляемого буфера не должен быть больше, чем 2**31 - 1.
  • offset <number> По умолчанию: 0
  • size <number> По умолчанию: buffer.length - offset. size не должен быть больше, чем 2**31 - 1.
  • Возвращает: {ArrayBuffer|Buffer|TypedArray|DataView} Объект, переданный в качестве аргумента buffer.

Синхронная версия crypto.randomFill().

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
import { Buffer } from 'node:buffer';
const { randomFillSync } = await import('node:crypto');

const buf = Buffer.alloc(10);
console.log(randomFillSync(buf).toString('hex'));

randomFillSync(buf, 5);
console.log(buf.toString('hex'));

// Вышеприведенное эквивалентно следующему:
randomFillSync(buf, 5, 5);
console.log(buf.toString('hex'));
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
const { randomFillSync } = require('node:crypto');
const { Buffer } = require('node:buffer');

const buf = Buffer.alloc(10);
console.log(randomFillSync(buf).toString('hex'));

randomFillSync(buf, 5);
console.log(buf.toString('hex'));

// Вышеприведенное эквивалентно следующему:
randomFillSync(buf, 5, 5);
console.log(buf.toString('hex'));

В качестве буфера может быть передан любой экземпляр ArrayBuffer, TypedArray или DataView.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
import { Buffer } from 'node:buffer';
const { randomFillSync } = await import('node:crypto');

const a = new Uint32Array(10);
console.log(
    Buffer.from(
        randomFillSync(a).buffer,
        a.byteOffset,
        a.byteLength
    ).toString('hex')
);

const b = new DataView(new ArrayBuffer(10));
console.log(
    Buffer.from(
        randomFillSync(b).buffer,
        b.byteOffset,
        b.byteLength
    ).toString('hex')
);

const c = new ArrayBuffer(10);
console.log(Buffer.from(randomFillSync(c)).toString('hex'));
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
const { randomFillSync } = require('node:crypto');
const { Buffer } = require('node:buffer');

const a = new Uint32Array(10);
console.log(
    Buffer.from(
        randomFillSync(a).buffer,
        a.byteOffset,
        a.byteLength
    ).toString('hex')
);

const b = new DataView(new ArrayBuffer(10));
console.log(
    Buffer.from(
        randomFillSync(b).buffer,
        b.byteOffset,
        b.byteLength
    ).toString('hex')
);

const c = new ArrayBuffer(10);
console.log(Buffer.from(randomFillSync(c)).toString('hex'));

crypto.randomFill(buffer[, offset][, size], callback)

  • buffer {ArrayBuffer|Buffer|TypedArray|DataView} Должен быть предоставлен. Размер предоставляемого буфера не должен быть больше, чем 2**31 - 1.
  • offset <number> По умолчанию: 0
  • size <number> По умолчанию: buffer.length - offset. size не должно быть больше, чем 2**31 - 1.
  • callback <Function> function(err, buf) {}.

Эта функция аналогична crypto.randomBytes(), но требует, чтобы первым аргументом был буфер, который будет заполнен. Она также требует, чтобы был передан обратный вызов.

Если функция callback не передана, будет выдана ошибка.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
import { Buffer } from 'node:buffer';
const { randomFill } = await import('node:crypto');

const buf = Buffer.alloc(10);
randomFill(buf, (err, buf) => {
    if (err) throw err;
    console.log(buf.toString('hex'));
});

randomFill(buf, 5, (err, buf) => {
    if (err) throw err;
    console.log(buf.toString('hex'));
});

// Вышеприведенное эквивалентно следующему:
randomFill(buf, 5, 5, (err, buf) => {
    if (err) throw err;
    console.log(buf.toString('hex'));
});
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
const { randomFill } = require('node:crypto');
const { Buffer } = require('node:buffer');

const buf = Buffer.alloc(10);
randomFill(buf, (err, buf) => {
    if (err) throw err;
    console.log(buf.toString('hex'));
});

randomFill(buf, 5, (err, buf) => {
    if (err) throw err;
    console.log(buf.toString('hex'));
});

// Вышеприведенное эквивалентно следующему:
randomFill(buf, 5, 5, (err, buf) => {
    if (err) throw err;
    console.log(buf.toString('hex'));
});

Любой экземпляр ArrayBuffer, TypedArray или DataView может быть передан в качестве buffer.

Хотя сюда входят экземпляры Float32Array и Float64Array, эта функция не должна использоваться для генерации случайных чисел с плавающей точкой. Результат может содержать +Infinity, -Infinity и NaN, и даже если массив содержит только конечные числа, они не взяты из равномерного случайного распределения и не имеют значимых нижних или верхних границ.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
import { Buffer } from 'node:buffer';
const { randomFill } = await import('node:crypto');

const a = new Uint32Array(10);
randomFill(a, (err, buf) => {
    if (err) throw err;
    console.log(
        Buffer.from(
            buf.buffer,
            buf.byteOffset,
            buf.byteLength
        ).toString('hex')
    );
});

const b = new DataView(new ArrayBuffer(10));
randomFill(b, (err, buf) => {
    if (err) throw err;
    console.log(
        Buffer.from(
            buf.buffer,
            buf.byteOffset,
            buf.byteLength
        ).toString('hex')
    );
});

const c = new ArrayBuffer(10);
randomFill(c, (err, buf) => {
    if (err) throw err;
    console.log(Buffer.from(buf).toString('hex'));
});
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
const { randomFill } = require('node:crypto');
const { Buffer } = require('node:buffer');

const a = new Uint32Array(10);
randomFill(a, (err, buf) => {
    if (err) throw err;
    console.log(
        Buffer.from(
            buf.buffer,
            buf.byteOffset,
            buf.byteLength
        ).toString('hex')
    );
});

const b = new DataView(new ArrayBuffer(10));
randomFill(b, (err, buf) => {
    if (err) throw err;
    console.log(
        Buffer.from(
            buf.buffer,
            buf.byteOffset,
            buf.byteLength
        ).toString('hex')
    );
});

const c = new ArrayBuffer(10);
randomFill(c, (err, buf) => {
    if (err) throw err;
    console.log(Buffer.from(buf).toString('hex'));
});

Этот API использует пул потоков libuv, что может иметь неожиданные и негативные последствия для производительности некоторых приложений; смотрите документацию UV_THREADPOOL_SIZE для получения дополнительной информации.

Асинхронная версия crypto.randomFill() выполняется за один запрос к пулу потоков. Чтобы минимизировать изменение длины задачи пула потоков, разделяйте большие запросы randomFill, если они выполняются в рамках выполнения запроса клиента.

crypto.randomInt([min, ]max[, callback])

  • min <integer> Начало произвольного диапазона (включительно). По умолчанию: 0.
    • max <integer> Конец случайного диапазона (включительно).
    • callback <Function> function(err, n) {}.

Возвращает случайное целое число n, такое, что min <= n < max. Эта реализация позволяет избежать modulo bias.

Диапазон (max - min) должен быть меньше 248. min и max должны быть безопасными целыми числами.

Если функция callback не предоставлена, случайное целое генерируется синхронно.

1
2
3
4
5
6
7
8
9
// Asynchronous
const { randomInt } = await import('node:crypto');

randomInt(3, (err, n) => {
    if (err) throw err;
    console.log(
        `Random number chosen from (0, 1, 2): ${n}`
    );
});
1
2
3
4
5
6
7
8
9
// Asynchronous
const { randomInt } = require('node:crypto');

randomInt(3, (err, n) => {
    if (err) throw err;
    console.log(
        `Случайное число, выбранное из (0, 1, 2): ${n}`
    );
});
1
2
3
4
5
6
7
// Синхронный
const { randomInt } = await import('node:crypto');

const n = randomInt(3);
console.log(
    `Случайное число, выбранное из (0, 1, 2): ${n}`
);
1
2
3
4
5
6
7
// Синхронный
const { randomInt } = require('node:crypto');

const n = randomInt(3);
console.log(
    `Случайное число, выбранное из (0, 1, 2): ${n}`
);
1
2
3
4
5
// С аргументом `min`
const { randomInt } = await import('node:crypto');

const n = randomInt(1, 7);
console.log(`Кубики брошены: ${n}`);
1
2
3
4
5
// С аргументом `min`
const { randomInt } = require('node:crypto');

const n = randomInt(1, 7);
console.log(`Кубики брошены: ${n}`);

crypto.randomUUID([options])

  • options <Object>
    • disableEntropyCache <boolean> По умолчанию, для повышения производительности, Node.js генерирует и кэширует достаточно случайных данных для генерации до 128 случайных UUID. Чтобы генерировать UUID без использования кэша, установите disableEntropyCache в true. По умолчанию: false.
  • Возвращает: <string>

Генерирует случайный RFC 4122 UUID версии 4. UUID генерируется с помощью криптографического генератора псевдослучайных чисел.

crypto.scrypt(password, salt, keylen[, options], callback)

  • пароль {string|ArrayBuffer|Buffer|TypedArray|DataView}
  • соль {string|ArrayBuffer|Buffer|TypedArray|DataView}
  • keylen <number>
  • options <Object>
    • cost <number> Параметр стоимости процессора/памяти. Должен быть на целых два больше единицы. По умолчанию: 16384.
    • blockSize <number> Параметр размера блока. По умолчанию: 8.
    • parallelization <number> Параметр распараллеливания. По умолчанию: 1.
    • N <number> Псевдоним для cost. Может быть указан только один из них.
    • r <number> Псевдоним для blockSize. Может быть указано только одно из обоих.
    • p <number> Псевдоним для распараллеливания. Может быть указано только одно из обоих значений.
    • maxmem <number> Верхняя граница памяти. Ошибкой будет, если (приблизительно) 128 * N * r > maxmem. По умолчанию: 32 * 1024 * 1024.
  • callback <Function>

Предоставляет асинхронную реализацию scrypt. Scrypt - это функция получения ключа на основе пароля, которая спроектирована так, чтобы быть дорогой в вычислительном плане и по памяти, чтобы сделать атаки "грубой силы" невыгодными.

Соль" должна быть настолько уникальной, насколько это возможно. Рекомендуется, чтобы соль была случайной и имела длину не менее 16 байт. Подробности см. в NIST SP 800-132.

При передаче строк для password или salt следует учитывать предостережения при использовании строк в качестве входных данных для криптографических API.

Функция callback вызывается с двумя аргументами: err и derivedKey. err - это объект исключения, если выведение ключа не удалось, в противном случае err - это null. derivedKey передается обратному вызову как Buffer.

Исключение возникает, если любой из входных аргументов содержит недопустимые значения или типы.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
const { scrypt } = await import('node:crypto');

// Использование заводских значений по умолчанию.
scrypt('password', 'salt', 64, (err, derivedKey) => {
    if (err) throw err;
    console.log(derivedKey.toString('hex')); // '3745e48...08d59ae'
});
// Использование пользовательского параметра N. Должен быть степенью двойки.
scrypt(
    'password',
    'salt',
    64,
    { N: 1024 },
    (err, derivedKey) => {
        if (err) throw err;
        console.log(derivedKey.toString('hex')); // '3745e48...aa39b34'
    }
);
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
const { scrypt } = require('node:crypto');

// Использование заводских настроек по умолчанию.
scrypt('password', 'salt', 64, (err, derivedKey) => {
    if (err) throw err;
    console.log(derivedKey.toString('hex')); // '3745e48...08d59ae'
});
// Использование пользовательского параметра N. Должен быть степенью двойки.
scrypt(
    'password',
    'salt',
    64,
    { N: 1024 },
    (err, derivedKey) => {
        if (err) throw err;
        console.log(derivedKey.toString('hex')); // '3745e48...aa39b34'
    }
);

crypto.scryptSync(password, salt, keylen[, options])

  • пароль <string> | <Buffer> | <TypedArray> | <DataView>
  • соль <string> | <Buffer> | <TypedArray> | <DataView>
  • keylen <number>
  • options <Object>
    • cost <number> Параметр стоимости процессора/памяти. Должен быть на целых два больше единицы. По умолчанию: 16384.
    • blockSize <number> Параметр размера блока. По умолчанию: 8.
    • parallelization <number> Параметр распараллеливания. По умолчанию: 1.
    • N <number> Псевдоним для cost. Может быть указан только один из них.
    • r <number> Псевдоним для blockSize. Может быть указано только одно из обоих.
    • p <number> Псевдоним для распараллеливания. Может быть указано только одно из обоих значений.
    • maxmem <number> Верхняя граница памяти. Ошибкой будет, если (приблизительно) 128 * N * r > maxmem. По умолчанию: 32 * 1024 * 1024.
  • Возвращает: <Buffer>

Предоставляет синхронную реализацию scrypt. Scrypt - это функция получения ключа на основе пароля, которая спроектирована так, чтобы быть дорогой в вычислительном плане и по памяти, чтобы сделать атаки "грубой силы" невыгодными.

Соль" должна быть настолько уникальной, насколько это возможно. Рекомендуется, чтобы соль была случайной и имела длину не менее 16 байт. Подробности см. в NIST SP 800-132.

При передаче строк для password или salt следует учитывать предостережения при использовании строк в качестве входов в криптографические API.

При неудачном выводе ключа возникает исключение, в противном случае полученный ключ возвращается как буфер.

Исключение возникает, если в любом из входных аргументов указаны недопустимые значения или типы.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
const { scryptSync } = await import('node:crypto');
// Использование заводских значений по умолчанию.

const key1 = scryptSync('password', 'salt', 64);
console.log(key1.toString('hex')); // '3745e48...08d59ae'
// Использование пользовательского параметра N. Должен быть степенью двойки.
const key2 = scryptSync('password', 'salt', 64, {
    N: 1024,
});
console.log(key2.toString('hex')); // '3745e48...aa39b34'
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
const { scryptSync } = require('node:crypto');
// Использование заводских настроек по умолчанию.

const key1 = scryptSync('password', 'salt', 64);
console.log(key1.toString('hex')); // '3745e48...08d59ae'
// Использование пользовательского параметра N. Должен быть степенью двойки.
const key2 = scryptSync('password', 'salt', 64, {
    N: 1024,
});
console.log(key2.toString('hex')); // '3745e48...aa39b34'

crypto.secureHeapUsed().

  • Возвращает: <Object>
    • total <number> Общий размер выделенной безопасной кучи, указанный с помощью флага командной строки --secure-heap=n.
    • min <number> Минимальное выделение из безопасной кучи, как указано с помощью флага командной строки --secure-heap-min.
    • used <number> Общее количество байт, выделенных в данный момент из безопасной кучи.
    • utilization <number> Рассчитанное отношение использованных к общему количеству выделенных байт.

crypto.setEngine(engine[, flags])

  • двигатель <string>
  • flags {crypto.constants} По умолчанию: crypto.constants.ENGINE_METHOD_ALL.

Загружает и устанавливает engine для некоторых или всех функций OpenSSL (выбранных флагами).

engine может быть либо идентификатором, либо путем к общей библиотеке движка.

Необязательный аргумент flags по умолчанию использует ENGINE_METHOD_ALL. flags - это битовое поле, принимающее один из следующих флагов (определенных в crypto.constants) или их смесь:

  • crypto.constants.ENGINE_METHOD_RSA
  • crypto.constants.ENGINE_METHOD_DSA
  • crypto.constants.ENGINE_METHOD_DH
  • crypto.constants.ENGINE_METHOD_RAND
  • crypto.constants.ENGINE_METHOD_EC
  • crypto.constants.ENGINE_METHOD_CIPHERS
  • crypto.constants.ENGINE_METHOD_DIGESTS
  • crypto.constants.ENGINE_METHOD_PKEY_METHS
  • crypto.constants.ENGINE_METHOD_PKEY_ASN1_METHS
  • crypto.constants.ENGINE_METHOD_ALL
  • crypto.constants.ENGINE_METHOD_NONE

crypto.setFips(bool)

  • bool <boolean> true для включения режима FIPS.

Включает FIPS-совместимый криптопровайдер в сборке Node.js с поддержкой FIPS. Выбрасывает ошибку, если режим FIPS недоступен.

crypto.sign(algorithm, data, key[, callback])

  • алгоритм {string | null | undefined}
  • данные {ArrayBuffer|Buffer|TypedArray|DataView}
  • key {Object|string|ArrayBuffer|Buffer|TypedArray|DataView|KeyObject|CryptoKey}
  • callback <Function>
  • Возвращает: <Buffer>, если функция callback не предоставлена.

Вычисляет и возвращает подпись для data, используя заданный закрытый ключ и алгоритм. Если algorithm равен null или undefined, то алгоритм зависит от типа ключа (особенно Ed25519 и Ed448).

Если key не является KeyObject, эта функция ведет себя так, как если бы key был передан в crypto.createPrivateKey(). Если это объект, могут быть переданы следующие дополнительные свойства:

  • dsaEncoding <string> Для DSA и ECDSA этот параметр определяет формат генерируемой подписи. Он может быть одним из следующих:

    • 'der (по умолчанию): DER-кодирование ASN.1 структуры подписи в кодировке (r, s).
    • 'ieee-p1363': Формат подписи r || s, предложенный в IEEE-P1363.
  • padding <integer> Необязательное значение прокладки для RSA, одно из следующих:

    • crypto.constants.RSA_PKCS1_PADDING (по умолчанию)
    • crypto.constants.RSA_PKCS1_PSS_PADDING

    RSA_PKCS1_PSS_PADDING будет использовать MGF1 с той же хэш-функцией, которая используется для подписи сообщения, как указано в разделе 3.1 RFC 4055.

  • saltLength <integer> Длина соли для случая, когда используется RSA_PKCS1_PSS_PADDING. Специальное значение crypto.constants.RSA_PSS_SALTLEN_DIGEST устанавливает длину соли в размер дайджеста, crypto.constants.RSA_PSS_SALTLEN_MAX_SIGN (по умолчанию) - в максимально допустимое значение.

Если указана функция callback, эта функция использует пул потоков libuv.

crypto.subtle

  • Тип: {SubtleCrypto}

Удобный псевдоним для crypto.webcrypto.subtle.

crypto.timingSafeEqual(a, b)

  • a {ArrayBuffer|Buffer|TypedArray|DataView}
  • b {ArrayBuffer|Buffer|TypedArray|DataView}
  • Возвращает: <boolean>

Эта функция сравнивает базовые байты, представляющие заданные экземпляры ArrayBuffer, TypedArray или DataView, используя алгоритм постоянного времени.

Эта функция не передает информацию о времени, которая позволила бы злоумышленнику угадать одно из значений. Она подходит для сравнения дайджестов HMAC или секретных значений, таких как аутентификационные cookies или capability urls.

a и b должны быть Buffer, TypedArray или DataView, и они должны иметь одинаковую длину байта. Если a и b имеют разную длину байта, будет выдана ошибка.

Если хотя бы один из a и b является TypedArray с более чем одним байтом на запись, например Uint16Array, результат будет вычислен с использованием порядка байтов платформы.

Когда оба входа являются Float32Array или Float64Array, эта функция может вернуть неожиданные результаты из-за кодировки IEEE 754 для чисел с плавающей точкой. В частности, ни x === y, ни Object.is(x, y) не означают, что байтовые представления двух чисел с плавающей точкой x и y равны.

Использование crypto.timingSafeEqual не гарантирует, что окружающий код безопасен по времени. Следует позаботиться о том, чтобы окружающий код не создавал уязвимостей во времени.

crypto.verify(algorithm, data, key, signature[, callback])

  • алгоритм {string|null|undefined}
  • данные {ArrayBuffer| Buffer|TypedArray|DataView}
  • ключ {Object|string|ArrayBuffer|Buffer|TypedArray|DataView|KeyObject|CryptoKey}
  • signature {ArrayBuffer|Buffer|TypedArray|DataView}
  • callback <Function>
  • Возвращает: <boolean> true или false в зависимости от достоверности подписи для данных и открытого ключа, если функция callback не предоставлена.

Проверяет заданную подпись для данных, используя заданный ключ и алгоритм. Если algorithm равен null или undefined, то алгоритм зависит от типа ключа (особенно Ed25519 и Ed448).

Если key не является KeyObject, эта функция ведет себя так, как если бы key был передан в crypto.createPublicKey(). Если это объект, могут быть переданы следующие дополнительные свойства:

  • dsaEncoding <string> Для DSA и ECDSA этот параметр определяет формат подписи. Он может быть одним из следующих:

    • 'der (по умолчанию): DER-кодирование ASN.1 структуры подписи в кодировке (r, s).
    • 'ieee-p1363': Формат подписи r || s, предложенный в IEEE-P1363.
  • padding <integer> Необязательное значение прокладки для RSA, одно из следующих:

    • crypto.constants.RSA_PKCS1_PADDING (по умолчанию)
    • crypto.constants.RSA_PKCS1_PSS_PADDING

    RSA_PKCS1_PSS_PADDING будет использовать MGF1 с той же хэш-функцией, которая используется для подписи сообщения, как указано в разделе 3.1 RFC 4055.

  • saltLength <integer> Длина соли для случая, когда используется RSA_PKCS1_PSS_PADDING. Специальное значение crypto.constants.RSA_PSS_SALTLEN_DIGEST устанавливает длину соли в размер дайджеста, crypto.constants.RSA_PSS_SALTLEN_MAX_SIGN (по умолчанию) - в максимально допустимое значение.

Аргумент signature - это ранее вычисленная подпись для данных.

Поскольку открытые ключи могут быть получены из закрытых ключей, для key может быть передан как закрытый, так и открытый ключ.

Если указана функция callback, эта функция использует пул потоков libuv.

crypto.webcrypto

Тип: {Crypto} Реализация стандарта Web Crypto API.

Подробности см. в документации Web Crypto API.

Примечания

Использование строк в качестве входов в криптографические API

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

При передаче строк в криптографические API следует учитывать следующие факторы.

  • Не все последовательности байтов являются допустимыми строками UTF-8. Поэтому, когда из строки получается последовательность байтов длиной n, ее энтропия обычно ниже, чем энтропия случайной или псевдослучайной последовательности байтов длиной n. Например, из строки UTF-8 не получится последовательность байтов c0 af. Секретные ключи должны быть почти исключительно случайными или псевдослучайными последовательностями байтов.

  • Аналогично, при преобразовании случайных или псевдослучайных последовательностей байтов в строки UTF-8, последовательности, не представляющие допустимые кодовые точки, могут быть заменены символом замены Unicode (U+FFFD). Поэтому байтовое представление результирующей строки Unicode может быть не равно последовательности байтов, из которой она была создана.

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    const original = [0xc0, 0xaf];
    const bytesAsString = Buffer.from(original).toString(
        'utf8'
    );
    const stringAsBytes = Buffer.from(
        bytesAsString,
        'utf8'
    );
    console.log(stringAsBytes);
    // Печатает '<Буфер ef bf bd ef bf bd>'.
    

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

  • Когда строки получаются из пользовательского ввода, некоторые символы Unicode могут быть представлены несколькими эквивалентными способами, которые приводят к различным последовательностям байтов. Например, при передаче парольной фразы пользователя функции выведения ключа, такой как PBKDF2 или scrypt, результат функции выведения ключа зависит от того, используются ли в строке составные или разложенные символы. Node.js не нормализует представления символов. Разработчикам следует рассмотреть возможность использования String.prototype.normalize() для пользовательского ввода перед передачей его в криптографические API.

Старый API потоков (до Node.js 0.10)

Модуль Crypto был добавлен в Node.js до появления концепции унифицированного Stream API, и до появления объектов Buffer для работы с двоичными данными. Поэтому многие классы, определяющие crypto, имеют методы, которые обычно не встречаются в других классах Node.js, реализующих API streams (например, update(), final() или digest()). Кроме того, многие методы по умолчанию принимали и возвращали строки в кодировке 'latin1', а не буфер. Это значение было изменено после Node.js v0.8 на использование объектов Buffer по умолчанию.

Поддержка слабых или скомпрометированных алгоритмов

Модуль node:crypto по-прежнему поддерживает некоторые алгоритмы, которые уже скомпрометированы и в настоящее время не рекомендуются для использования. API также позволяет использовать шифры и хэши с небольшим размером ключа, которые слишком слабы для безопасного использования.

Пользователи должны взять на себя полную ответственность за выбор криптоалгоритма и размера ключа в соответствии со своими требованиями к безопасности.

В соответствии с рекомендациями NIST SP 800-131A:

  • MD5 и SHA-1 больше не приемлемы там, где требуется устойчивость к коллизиям, например, в цифровых подписях.
  • Ключ, используемый в алгоритмах RSA, DSA и DH, рекомендуется иметь не менее 2048 бит, а ключ кривой ECDSA и ECDH - не менее 224 бит, чтобы его можно было безопасно использовать в течение нескольких лет.
  • Группы DH modp1, modp2 и modp5 имеют размер ключа меньше 2048 бит и не рекомендуются.

Другие рекомендации и подробности см. в справочнике.

Некоторые алгоритмы, имеющие известные недостатки и малоприменимые на практике, доступны только через legacy provider, который не включен по умолчанию.

Режим CCM

CCM является одним из поддерживаемых AEAD алгоритмов. Приложения, использующие этот режим, должны придерживаться определенных ограничений при использовании API шифра:

  • Длина тега аутентификации должна быть указана при создании шифра путем установки опции authTagLength и должна быть одной из 4, 6, 8, 10, 12, 14 или 16 байт.
  • Длина вектора инициализации (nonce) N должна быть от 7 до 13 байт (7 ≤ N ≤ 13).
  • Длина открытого текста ограничена 2 ** (8 * (15 - N)) байтами.
  • При расшифровке тег аутентификации должен быть установлен с помощью setAuthTag() перед вызовом update(). В противном случае расшифровка будет неудачной, и final() выдаст ошибку в соответствии с разделом 2.6 RFC 3610.
  • Использование потоковых методов, таких как write(data), end(data) или pipe() в режиме CCM может быть неудачным, так как CCM не может обрабатывать более одного куска данных на экземпляр.
  • При передаче дополнительных аутентифицированных данных (AAD), длина фактического сообщения в байтах должна быть передана в setAAD() через опцию plaintextLength. Многие криптобиблиотеки включают тег аутентификации в шифротекст, что означает, что они создают шифротексты длиной plaintextLength + authTagLength. Node.js не включает тег аутентификации, поэтому длина шифротекста всегда равна plaintextLength. Это не требуется, если не используется AAD.
  • Поскольку CCM обрабатывает все сообщение сразу, update() должна быть вызвана ровно один раз.
  • Даже если вызова update() достаточно для шифрования/дешифрования сообщения, приложения должны вызывать final() для вычисления или проверки метки аутентификации.
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
import { Buffer } from 'node:buffer';
const {
    createCipheriv,
    createDecipheriv,
    randomBytes,
} = await import('node:crypto');

const key = 'keykeykeykeykeykeykeykey';
const nonce = randomBytes(12);

const aad = Buffer.from('0123456789', 'hex');

const cipher = createCipheriv('aes-192-ccm', key, nonce, {
    authTagLength: 16,
});
const plaintext = 'Hello world';
cipher.setAAD(aad, {
    plaintextLength: Buffer.byteLength(plaintext),
});
const ciphertext = cipher.update(plaintext, 'utf8');
cipher.final();
const tag = cipher.getAuthTag();

// Now transmit { ciphertext, nonce, tag }.

const decipher = createDecipheriv(
    'aes-192-ccm',
    key,
    nonce,
    {
        authTagLength: 16,
    }
);
decipher.setAuthTag(tag);
decipher.setAAD(aad, {
    plaintextLength: ciphertext.length,
});
const receivedPlaintext = decipher.update(
    ciphertext,
    null,
    'utf8'
);

try {
    decipher.final();
} catch (err) {
    throw new Error('Authentication failed!', {
        cause: err,
    });
}

console.log(receivedPlaintext);
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
const { Buffer } = require('node:buffer');
const {
    createCipheriv,
    createDecipheriv,
    randomBytes,
} = require('node:crypto');

const key = 'keykeykeykeykeykeykeykey';
const nonce = randomBytes(12);

const aad = Buffer.from('0123456789', 'hex');

const cipher = createCipheriv('aes-192-ccm', key, nonce, {
    authTagLength: 16,
});
const plaintext = 'Hello world';
cipher.setAAD(aad, {
    plaintextLength: Buffer.byteLength(plaintext),
});
const ciphertext = cipher.update(plaintext, 'utf8');
cipher.final();
const tag = cipher.getAuthTag();

// Now transmit { ciphertext, nonce, tag }.

const decipher = createDecipheriv(
    'aes-192-ccm',
    key,
    nonce,
    {
        authTagLength: 16,
    }
);
decipher.setAuthTag(tag);
decipher.setAAD(aad, {
    plaintextLength: ciphertext.length,
});
const receivedPlaintext = decipher.update(
    ciphertext,
    null,
    'utf8'
);

try {
    decipher.final();
} catch (err) {
    throw new Error('Authentication failed!', {
        cause: err,
    });
}

console.log(receivedPlaintext);

Константы криптографии

Следующие константы, экспортируемые crypto.constants, применяются к различным вариантам использования модулей node:crypto, node:tls и node:https и в целом специфичны для OpenSSL.

OpenSSL options

See the list of SSL OP Flags for details.

Constant Description
SSL_OP_ALL Applies multiple bug workarounds within OpenSSL. See https://www.openssl.org/docs/man3.0/man3/SSL_CTX_set_options.html for detail.
SSL_OP_ALLOW_NO_DHE_KEX Instructs OpenSSL to allow a non-\[EC\]DHE-based key exchange mode for TLS v1.3
SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION Allows legacy insecure renegotiation between OpenSSL and unpatched clients or servers. See https://www.openssl.org/docs/man3.0/man3/SSL_CTX_set_options.html.
SSL_OP_CIPHER_SERVER_PREFERENCE Attempts to use the server’s preferences instead of the client’s when selecting a cipher. Behavior depends on protocol version. See https://www.openssl.org/docs/man3.0/man3/SSL_CTX_set_options.html.
SSL_OP_CISCO_ANYCONNECT Instructs OpenSSL to use Cisco’s “speshul” version of DTLS_BAD_VER.
SSL_OP_COOKIE_EXCHANGE Instructs OpenSSL to turn on cookie exchange.
SSL_OP_CRYPTOPRO_TLSEXT_BUG Instructs OpenSSL to add server-hello extension from an early version of the cryptopro draft.
SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS Instructs OpenSSL to disable a SSL 3.0/TLS 1.0 vulnerability workaround added in OpenSSL 0.9.6d.
SSL_OP_LEGACY_SERVER_CONNECT Allows initial connection to servers that do not support RI.
SSL_OP_NO_COMPRESSION Instructs OpenSSL to disable support for SSL/TLS compression.
SSL_OP_NO_ENCRYPT_THEN_MAC Instructs OpenSSL to disable encrypt-then-MAC.
SSL_OP_NO_QUERY_MTU
SSL_OP_NO_RENEGOTIATION Instructs OpenSSL to disable renegotiation.
SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION Instructs OpenSSL to always start a new session when performing renegotiation.
SSL_OP_NO_SSLv2 Instructs OpenSSL to turn off SSL v2
SSL_OP_NO_SSLv3 Instructs OpenSSL to turn off SSL v3
SSL_OP_NO_TICKET Instructs OpenSSL to disable use of RFC4507bis tickets.
SSL_OP_NO_TLSv1 Instructs OpenSSL to turn off TLS v1
SSL_OP_NO_TLSv1_1 Instructs OpenSSL to turn off TLS v1.1
SSL_OP_NO_TLSv1_2 Instructs OpenSSL to turn off TLS v1.2
SSL_OP_NO_TLSv1_3 Instructs OpenSSL to turn off TLS v1.3
SSL_OP_PRIORITIZE_CHACHA Instructs OpenSSL server to prioritize ChaCha20-Poly1305 when the client does. This option has no effect if SSL_OP_CIPHER_SERVER_PREFERENCE is not enabled.
SSL_OP_TLS_ROLLBACK_BUG Instructs OpenSSL to disable version rollback attack detection.

OpenSSL engine constants

Constant Description
ENGINE_METHOD_RSA Limit engine usage to RSA
ENGINE_METHOD_DSA Limit engine usage to DSA
ENGINE_METHOD_DH Limit engine usage to DH
ENGINE_METHOD_RAND Limit engine usage to RAND
ENGINE_METHOD_EC Limit engine usage to EC
ENGINE_METHOD_CIPHERS Limit engine usage to CIPHERS
ENGINE_METHOD_DIGESTS Limit engine usage to DIGESTS
ENGINE_METHOD_PKEY_METHS Limit engine usage to PKEY_METHDS
ENGINE_METHOD_PKEY_ASN1_METHS Limit engine usage to PKEY_ASN1_METHS
ENGINE_METHOD_ALL
ENGINE_METHOD_NONE

Other OpenSSL constants

Constant Description
DH_CHECK_P_NOT_SAFE_PRIME
DH_CHECK_P_NOT_PRIME
DH_UNABLE_TO_CHECK_GENERATOR
DH_NOT_SUITABLE_GENERATOR
RSA_PKCS1_PADDING
RSA_SSLV23_PADDING
RSA_NO_PADDING
RSA_PKCS1_OAEP_PADDING
RSA_X931_PADDING
RSA_PKCS1_PSS_PADDING
RSA_PSS_SALTLEN_DIGEST Sets the salt length for RSA_PKCS1_PSS_PADDING to the digest size when signing or verifying.
RSA_PSS_SALTLEN_MAX_SIGN Sets the salt length for RSA_PKCS1_PSS_PADDING to the maximum permissible value when signing data.
RSA_PSS_SALTLEN_AUTO Causes the salt length for RSA_PKCS1_PSS_PADDING to be determined automatically when verifying a signature.
POINT_CONVERSION_COMPRESSED
POINT_CONVERSION_UNCOMPRESSED
POINT_CONVERSION_HYBRID

Node.js crypto constants

Constant Description
defaultCoreCipherList Specifies the built-in default cipher list used by Node.js.
defaultCipherList Specifies the active default cipher list used by the current Node.js process.

Комментарии