Криптография
Модуль crypto предоставляет криптографические функции, включающие набор обёртки для функций OpenSSL's hash, HMAC, шифрования, расшифровки, подписи и проверки подписи.
Используйте require('crypto') для доступа к этому модулю.
const crypto = require('crypto');
const secret = 'abcdefg';
const hash = crypto.createHmac('sha256', secret)
.update('I love cupcakes')
.digest('hex');
console.log(hash);
// Prints:
// c0fa1bc00531bd78ef38c628449c5102aeabd49b5dc3a2a516ea6ea959d6658e
Класс: Certificate
SPKAC — это механизм запросов на подпись сертификатов, первоначально реализованный компанией Netscape и теперь формально определён как часть элемента HTML5 keygen.
Модуль crypto предоставляет класс Certificate для работы с данными SPKAC. Наиболее распространённое использование — обработка вывода, генерируемого элементом HTML5 <keygen>. Node.js использует внутреннюю реализацию SPKAC OpenSSL.
new crypto.Certificate()
Экземпляры класса Certificate можно создать, используя ключевое слово new или вызвав crypto.Certificate() как функцию:
const crypto = require('crypto');
const cert1 = new crypto.Certificate();
const cert2 = crypto.Certificate();
certificate.exportChallenge(spkac)
Структура данных spkac включает открытый ключ и запрос. Метод certificate.exportChallenge() возвращает компонент запроса в формате Node.js Buffer. Аргумент spkac может быть строкой или Buffer.
const cert = require('crypto').Certificate();
const spkac = getSpkacSomehow();
const challenge = cert.exportChallenge(spkac);
console.log(challenge.toString('utf8'));
// Prints the challenge as a UTF8 string
certificate.exportPublicKey(spkac)
Структура данных spkac включает открытый ключ и запрос. Метод certificate.exportPublicKey() возвращает компонент открытого ключа в формате Node.js Buffer. Аргумент spkac может быть строкой или Buffer.
const cert = require('crypto').Certificate();
const spkac = getSpkacSomehow();
const publicKey = cert.exportPublicKey(spkac);
console.log(publicKey);
// Prints the public key as <Buffer ...>
certificate.verifySpkac(spkac)
Возвращает true, если заданная структура данных spkac валидна, false в противном случае. Аргумент spkac должен быть Node.js Buffer.
const cert = require('crypto').Certificate();
const spkac = getSpkacSomehow();
console.log(cert.verifySpkac(new Buffer(spkac)));
// Prints true or false
Класс: Шифр
Экземпляры класса Cipher используются для шифрования данных. Класс может быть использован двумя способами:
- В качестве потока потока, который одновременно читаемый и записываемый, где нешифрованные данные записываются для получения зашифрованных данных на стороне чтения,
- Используя методы
cipher.update()иcipher.final()для получения зашифрованных данных.
Для создания экземпляров Cipher используются методы crypto.createCipher() или crypto.createCipheriv(). Экземпляры Cipher не должны создаваться напрямую с использованием ключевого слова new
Пример: Использование объектов Cipher в качестве потоков:
const crypto = require('crypto');
const cipher = crypto.createCipher('aes192', 'a password');
var encrypted = '';
cipher.on('readable', () => {
var data = cipher.read();
if (data)
encrypted += data.toString('hex');
});
cipher.on('end', () => {
console.log(encrypted);
// Prints: ca981be48e90867604588e75d04feabb63cc007a8f8ad89b10616ed84d815504
});
cipher.write('some clear text data');
cipher.end();
Пример: Использование Cipher и потоков со сквозной передачей данных:
const crypto = require('crypto');
const fs = require('fs');
const cipher = crypto.createCipher('aes192', 'a password');
const input = fs.createReadStream('test.js');
const output = fs.createWriteStream('test.enc');
input.pipe(cipher).pipe(output);
Пример: Использование методов cipher.update() и cipher.final():
const crypto = require('crypto');
const cipher = crypto.createCipher('aes192', 'a password');
var encrypted = cipher.update('some clear text data', 'utf8', 'hex');
encrypted += cipher.final('hex');
console.log(encrypted);
// Prints: ca981be48e90867604588e75d04feabb63cc007a8f8ad89b10616ed84d815504
cipher.final([output_encoding])
Возвращает любые оставшиеся зашифрованные данные. Если параметр output_encoding имеет одно из значений 'binary', 'base64' или 'hex', возвращается строка. Если параметр output_encoding не указан, возвращается Buffer.
После вызова метода cipher.final(), объект Cipher больше не может использоваться для шифрования данных. Попытки вызвать cipher.final() более одного раза приведут к ошибке.
cipher.setAAD(buffer)
При использовании режима аутентифицированного шифрования (в настоящее время поддерживается только GCM), метод cipher.setAAD() устанавливает значение, используемое для входного параметра дополнительных аутентифицированных данных (AAD).
cipher.getAuthTag()
При использовании режима аутентифицированного шифрования (в настоящее время поддерживается только GCM), метод cipher.getAuthTag() возвращает Buffer содержащий тег аутентификации, вычисленный на основе заданных данных.
Метод cipher.getAuthTag() должен вызываться только после завершения шифрования с помощью метода cipher.final().
cipher.setAutoPadding(auto_padding=true)
При использовании блочных алгоритмов шифрования, класс Cipher автоматически добавляет заполнение входных данных до соответствующего размера блока. Для отключения стандартного заполнения вызовите cipher.setAutoPadding(false)
Когда auto_padding равно false, длина всех входных данных должна быть кратна размеру блока шифра, иначе метод cipher.final() выбросит ошибку. Отключение автоматического заполнения полезно для нестандартного заполнения, например, используя 0x0 вместо PKCS-заполнения.
Метод cipher.setAutoPadding() должен вызываться перед cipher.final().
cipher.update(data[, input_encoding][, output_encoding])
Обновляет шифр с помощью data. Если указан аргумент input_encoding, его значение должно быть одним из 'utf8', 'ascii', или 'binary', а аргумент data — строкой, использующей указанную кодировку. Если аргумент input_encoding не указан, аргумент data должен быть Buffer. Если data является Buffer, то аргумент input_encoding игнорируется.
output_encoding указывает формат выходных зашифрованных данных и может быть 'binary', 'base64' или 'hex'. Если output_encoding указан, возвращается строка, использующая указанную кодировку. Если output_encoding не указан, возвращается Buffer.
Метод cipher.update() может вызываться несколько раз с новыми данными, пока не будет вызван cipher.final(). Вызов cipher.update() после cipher.final() приведет к ошибке.
Класс: Расшифровка
Экземпляры класса Decipher используются для расшифровки данных. Класс может быть использован двумя способами:
- В качестве потока потока, который одновременно читаемый и записываемый, где зашифрованные данные записываются для получения незашифрованных данных на стороне чтения,
- Используя методы
decipher.update()иdecipher.final()для получения незашифрованных данных.
Для создания экземпляров Decipher используются методы crypto.createDecipher() или crypto.createDecipheriv(). Экземпляры Decipher не должны создаваться напрямую с использованием ключевого слова new
Пример: Использование объектов Decipher в качестве потоков:
const crypto = require('crypto');
const decipher = crypto.createDecipher('aes192', 'a password');
var decrypted = '';
decipher.on('readable', () => {
var data = decipher.read();
if (data)
decrypted += data.toString('utf8');
});
decipher.on('end', () => {
console.log(decrypted);
// Prints: some clear text data
});
var encrypted = 'ca981be48e90867604588e75d04feabb63cc007a8f8ad89b10616ed84d815504';
decipher.write(encrypted, 'hex');
decipher.end();
Пример: Использование Decipher и потоков со сквозной передачей данных:
const crypto = require('crypto');
const fs = require('fs');
const decipher = crypto.createDecipher('aes192', 'a password');
const input = fs.createReadStream('test.enc');
const output = fs.createWriteStream('test.js');
input.pipe(decipher).pipe(output);
Пример: Использование методов decipher.update() и decipher.final():
const crypto = require('crypto');
const decipher = crypto.createDecipher('aes192', 'a password');
var encrypted = 'ca981be48e90867604588e75d04feabb63cc007a8f8ad89b10616ed84d815504';
var decrypted = decipher.update(encrypted, 'hex', 'utf8');
decrypted += decipher.final('utf8');
console.log(decrypted);
// Prints: some clear text data
decipher.final([output_encoding])
Возвращает любые оставшиеся расшифрованные данные. Если параметр output_encoding имеет одно из значений 'binary', 'base64' или 'hex', возвращается строка. Если параметр output_encoding не указан, возвращается Buffer.
После вызова метода decipher.final(), объект Decipher больше не может использоваться для расшифровки данных. Попытки вызвать decipher.final() более одного раза приведут к ошибке.
decipher.setAAD(buffer)
При использовании режима аутентифицированного шифрования (в настоящее время поддерживается только GCM), метод decipher.setAAD() устанавливает значение, используемое для входного параметра дополнительных аутентифицированных данных (AAD).
decipher.setAuthTag(buffer)
При использовании режима аутентифицированного шифрования (в настоящее время поддерживается только GCM), метод decipher.setAuthTag() используется для передачи полученного тега аутентификации. Если тег не предоставлен или текст шифротекста был изменён, метод decipher.final() выбросит ошибку, указывая, что текст шифротекста следует отбросить из-за неудачной аутентификации.
decipher.setAutoPadding(auto_padding=true)
При шифровании данных без стандартного заполнения блока, вызов decipher.setAutoPadding(false) отключит автоматическое заполнение, чтобы предотвратить проверку и удаление заполнения в методе decipher.final().
Отключение автоматического заполнения будет работать только в том случае, если длина входных данных кратна размеру блока шифра.
Метод decipher.setAutoPadding() необходимо вызвать перед decipher.update().
decipher.update(data[, input_encoding][, output_encoding])
Обновляет дешифратор с помощью data. Если аргумент input_encoding указан, его значение должно быть одним из 'binary', 'base64', или 'hex', а аргумент data — строкой, использующей указанную кодировку. Если аргумент input_encoding не указан, data должен быть Buffer. Если data является Buffer, то input_encoding игнорируется.
output_encoding задаёт формат вывода зашифрованных данных и может быть 'binary', 'ascii' или 'utf8'. Если output_encoding указан, возвращается строка, использующая указанную кодировку. Если output_encoding не указан, возвращается Buffer.
Метод decipher.update() можно вызывать несколько раз с новыми данными, пока не будет вызван decipher.final(). Вызов decipher.update() после decipher.final() приведёт к ошибке.
Класс: DiffieHellman
Класс DiffieHellman — это утилита для создания обмена ключами Диффи-Хеллмана.
Экземпляры класса DiffieHellman можно создать с помощью функции crypto.createDiffieHellman().
const crypto = require('crypto');
const assert = require('assert');
// Generate Alice's keys...
const alice = crypto.createDiffieHellman(2048);
const alice_key = alice.generateKeys();
// Generate Bob's keys...
const bob = crypto.createDiffieHellman(alice.getPrime(), alice.getGenerator());
const bob_key = bob.generateKeys();
// Exchange and generate the secret...
const alice_secret = alice.computeSecret(bob_key);
const bob_secret = bob.computeSecret(alice_key);
// OK
assert.equal(alice_secret.toString('hex'), bob_secret.toString('hex'));
diffieHellman.computeSecret(other_public_key[, input_encoding][, output_encoding])
Вычисляет общий секрет, используя other_public_key в качестве открытого ключа другой стороны и возвращает вычисленный общий секрет. Предоставленный ключ интерпретируется с использованием указанной input_encoding, а секрет кодируется с использованием указанной output_encoding. Кодировки могут быть 'binary', 'hex', или 'base64'. Если input_encoding не указана, other_public_key ожидается как Buffer.
Если output_encoding указана, возвращается строка; в противном случае — Buffer.
diffieHellman.generateKeys([encoding])
Генерирует значения закрытого и открытого ключей Диффи-Хеллмана и возвращает открытый ключ в указанной encoding. Этот ключ должен быть передан другой стороне. Кодировка может быть 'binary', 'hex', или 'base64'. Если encoding указана, возвращается строка; в противном случае — Buffer.
diffieHellman.getGenerator([encoding])
Возвращает генератор Диффи-Хеллмана в указанной encoding, которая может быть 'binary', 'hex', или 'base64'. Если encoding указана, возвращается строка; в противном случае — Buffer.
diffieHellman.getPrime([encoding])
Возвращает простое число Диффи-Хеллмана в указанной encoding, которая может быть 'binary', 'hex', или 'base64'. Если encoding указана, возвращается строка; в противном случае — Buffer.
diffieHellman.getPrivateKey([encoding])
Возвращает закрытый ключ Диффи-Хеллмана в указанной encoding, которая может быть 'binary', 'hex', или 'base64'. Если encoding указана, возвращается строка; в противном случае — Buffer.
diffieHellman.getPublicKey([encoding])
Возвращает открытый ключ Диффи-Хеллмана в указанной encoding, которая может быть 'binary', 'hex', или 'base64'. Если encoding указана, возвращается строка; в противном случае — Buffer.
diffieHellman.setPrivateKey(private_key[, encoding])
Устанавливает закрытый ключ Диффи-Хеллмана. Если аргумент encoding указан и равен 'binary', 'hex', или 'base64', private_key ожидается как строка. Если encoding не указан, private_key ожидается как Buffer.
diffieHellman.setPublicKey(public_key[, encoding])
Устанавливает открытый ключ Диффи-Хеллмана. Если аргумент encoding указан и равен 'binary', 'hex' или 'base64', public_key ожидается как строка. Если encoding не указан, public_key ожидается как Buffer.
diffieHellman.verifyError
Поле битовых флагов, содержащее любые предупреждения и/или ошибки, возникшие в ходе проверки, выполненной во время инициализации объекта DiffieHellman.
Следующие значения допустимы для этого свойства (как определено в модуле constants):
DH_CHECK_P_NOT_SAFE_PRIMEDH_CHECK_P_NOT_PRIMEDH_UNABLE_TO_CHECK_GENERATORDH_NOT_SUITABLE_GENERATOR
Класс: ECDH
Класс ECDH — это утилита для создания обменов ключами Эллиптической кривой Диффи-Хеллмана (ECDH).
Экземпляры класса ECDH можно создать с помощью функции crypto.createECDH().
const crypto = require('crypto');
const assert = require('assert');
// Generate Alice's keys...
const alice = crypto.createECDH('secp521r1');
const alice_key = alice.generateKeys();
// Generate Bob's keys...
const bob = crypto.createECDH('secp521r1');
const bob_key = bob.generateKeys();
// Exchange and generate the secret...
const alice_secret = alice.computeSecret(bob_key);
const bob_secret = bob.computeSecret(alice_key);
assert(alice_secret, bob_secret);
// OK
ecdh.computeSecret(other_public_key[, input_encoding][, output_encoding])
Вычисляет общий секрет, используя other_public_key в качестве открытого ключа другой стороны и возвращает вычисленный общий секрет. Предоставленный ключ интерпретируется с использованием указанной input_encoding, а возвращаемый секрет кодируется с использованием указанной output_encoding. Кодировки могут быть 'binary', 'hex', или 'base64'. Если input_encoding не указана, other_public_key ожидается как Buffer.
Если output_encoding указана, возвращается строка; в противном случае — Buffer.
ecdh.generateKeys([encoding[, format]])
Генерирует значения закрытого и открытого ключей EC Диффи-Хеллмана и возвращает открытый ключ в указанных format и encoding. Этот ключ должен быть передан другой стороне.
Аргумент format задаёт кодировку точки и может быть 'compressed', 'uncompressed', или 'hybrid'. Если format не указан, точка будет возвращена в формате 'uncompressed'.
Аргумент encoding может быть 'binary', 'hex', или 'base64'. Если encoding указана, возвращается строка; в противном случае — Buffer.
ecdh.getPrivateKey([encoding])
Возвращает закрытый ключ EC Диффи-Хеллмана в указанной encoding, которая может быть 'binary', 'hex', или 'base64'. Если encoding указана, возвращается строка; в противном случае — Buffer.
ecdh.getPublicKey([encoding[, format]])
Возвращает открытый ключ EC Диффи-Хеллмана в указанных encoding и format.
Аргумент format задаёт кодировку точки и может быть 'compressed', 'uncompressed', или 'hybrid'. Если format не указан, точка будет возвращена в формате 'uncompressed'.
Аргумент encoding может быть 'binary', 'hex', или 'base64'. Если encoding указана, возвращается строка; в противном случае — Buffer.
ecdh.setPrivateKey(private_key[, encoding])
Устанавливает закрытый ключ EC Диффи-Хеллмана. encoding может быть 'binary', 'hex' или 'base64'. Если encoding указан, private_key ожидается как строка; в противном случае private_key ожидается как Buffer. Если private_key не является допустимым для кривой, указанной при создании объекта ECDH, вызывается ошибка. При установке закрытого ключа, связанная открытая точка (ключ) также генерируется и устанавливается в объекте ECDH.
ecdh.setPublicKey(public_key[, encoding])
Устанавливает открытый ключ EC Diffie-Hellman. Кодировка ключа может быть 'binary', 'hex' или 'base64'. Если предоставлен encoding, ожидается, что public_key будет строкой; в противном случае ожидается Buffer.
Обратите внимание, что обычно нет необходимости вызывать этот метод, потому что ECDH требует только закрытого ключа и открытого ключа другой стороны для вычисления общего секрета. Обычно вызывается либо ecdh.generateKeys(), либо ecdh.setPrivateKey(). Метод ecdh.setPrivateKey() пытается сгенерировать открытую точку/ключ, связанную с устанавливаемым закрытым ключом.
Пример (получение общего секрета):
const crypto = require('crypto');
const alice = crypto.createECDH('secp256k1');
const bob = crypto.createECDH('secp256k1');
// Note: This is a shortcut way to specify one of Alice's previous private
// keys. It would be unwise to use such a predictable private key in a real
// application.
alice.setPrivateKey(
crypto.createHash('sha256').update('alice', 'utf8').digest()
);
// Bob uses a newly generated cryptographically strong
// pseudorandom key pair bob.generateKeys();
const alice_secret = alice.computeSecret(bob.getPublicKey(), null, 'hex');
const bob_secret = bob.computeSecret(alice.getPublicKey(), null, 'hex');
// alice_secret and bob_secret should be the same shared secret value
console.log(alice_secret === bob_secret);
Класс: Hash
Класс Hash — это утилита для создания хэш-дайджестов данных. Его можно использовать двумя способами:
- В качестве потока, который является как читаемым, так и записываемым, где данные записываются для вычисления хэш-дайджеста на стороне чтения, или
- Используя методы
hash.update()иhash.digest()для получения вычисленного хэша.
Метод crypto.createHash() используется для создания экземпляров Hash. Экземпляры Hash не должны создаваться напрямую с помощью ключевого слова new.
Пример: Использование объектов Hash в качестве потоков:
const crypto = require('crypto');
const hash = crypto.createHash('sha256');
hash.on('readable', () => {
var data = hash.read();
if (data)
console.log(data.toString('hex'));
// Prints:
// 6a2da20943931e9834fc12cfe5bb47bbd9ae43489a30726962b576f4e3993e50
});
hash.write('some data to hash');
hash.end();
Пример: Использование объектов Hash и потоков с передачей данных:
const crypto = require('crypto');
const fs = require('fs');
const hash = crypto.createHash('sha256');
const input = fs.createReadStream('test.js');
input.pipe(hash).pipe(process.stdout);
Пример: Использование методов hash.update() и hash.digest():
const crypto = require('crypto');
const hash = crypto.createHash('sha256');
hash.update('some data to hash');
console.log(hash.digest('hex'));
// Prints:
// 6a2da20943931e9834fc12cfe5bb47bbd9ae43489a30726962b576f4e3993e50
hash.digest([encoding])
Вычисляет дайджест всех данных, переданных для хэширования (с использованием метода hash.update()). Формат encoding может быть 'hex', 'binary' или 'base64'. Если предоставлен encoding, возвращается строка; в противном случае возвращается Buffer.
Объект Hash нельзя использовать повторно после вызова метода hash.digest(). Несколько вызовов приведут к ошибке.
hash.update(data[, input_encoding])
Обновляет содержимое хэша с заданными data, кодировка которых указана в input_encoding и может быть 'utf8', 'ascii' или 'binary'. Если encoding не указан, и data — строка, используется кодировка 'binary'. Если data — Buffer, то input_encoding игнорируется.
Это можно вызывать многократно с новыми данными по мере их поступления.
Класс: Hmac
Класс Hmac — это утилита для создания криптографических дайджестов HMAC. Его можно использовать двумя способами:
- В качестве потока, который является как читаемым, так и записываемым, где данные записываются для вычисления HMAC-дайджеста на стороне чтения, или
- Используя методы
hmac.update()иhmac.digest()для получения вычисленного HMAC-дайджеста.
Метод crypto.createHmac() используется для создания экземпляров Hmac. Экземпляры Hmac не должны создаваться напрямую с помощью ключевого слова new.
Пример: Использование объектов Hmac в качестве потоков:
const crypto = require('crypto');
const hmac = crypto.createHmac('sha256', 'a secret');
hmac.on('readable', () => {
var data = hmac.read();
if (data)
console.log(data.toString('hex'));
// Prints:
// 7fd04df92f636fd450bc841c9418e5825c17f33ad9c87c518115a45971f7f77e
});
hmac.write('some data to hash');
hmac.end();
Пример: Использование объектов Hmac и потоков с передачей данных:
const crypto = require('crypto');
const fs = require('fs');
const hmac = crypto.createHmac('sha256', 'a secret');
const input = fs.createReadStream('test.js');
input.pipe(hmac).pipe(process.stdout);
Пример: Использование методов hmac.update() и hmac.digest():
const crypto = require('crypto');
const hmac = crypto.createHmac('sha256', 'a secret');
hmac.update('some data to hash');
console.log(hmac.digest('hex'));
// Prints:
// 7fd04df92f636fd450bc841c9418e5825c17f33ad9c87c518115a45971f7f77e
hmac.digest([encoding])
Вычисляет HMAC-дайджест всех данных, прошедших через hmac.update(). Кодировка encoding может быть 'hex', 'binary' или 'base64'. Если предоставлен encoding, возвращается строка; в противном случае возвращается Buffer.
Объект Hmac нельзя использовать повторно после вызова hmac.digest(). Несколько вызовов hmac.digest() приведут к ошибке.
hmac.update(data[, input_encoding])
Обновляет содержимое Hmac с заданными data, кодировка которых указана в input_encoding и может быть 'utf8', 'ascii' или 'binary'. Если encoding не указан, и data — строка, используется кодировка 'utf8'. Если data — Buffer, то input_encoding игнорируется.
Это можно вызывать многократно с новыми данными по мере их поступления.
Класс: Sign
Класс Sign — это утилита для создания подписей. Его можно использовать двумя способами:
- В качестве записываемого потока, куда записываются данные для подписи, а метод
sign.sign()используется для генерации и возврата подписи, или - Используя методы
sign.update()иsign.sign()для получения подписи.
Метод crypto.createSign() используется для создания экземпляров Sign. Экземпляры Sign не должны создаваться напрямую с помощью ключевого слова new.
Пример: Использование объектов Sign в качестве потоков:
const crypto = require('crypto');
const sign = crypto.createSign('RSA-SHA256');
sign.write('some data to sign');
sign.end();
const private_key = getPrivateKeySomehow();
console.log(sign.sign(private_key, 'hex'));
// Prints the calculated signature
Пример: Использование методов sign.update() и sign.sign():
const crypto = require('crypto');
const sign = crypto.createSign('RSA-SHA256');
sign.update('some data to sign');
const private_key = getPrivateKeySomehow();
console.log(sign.sign(private_key, 'hex'));
// Prints the calculated signature
Экземпляр Sign также можно создать, просто передав имя алгоритма дайджеста, в этом случае OpenSSL определит полный алгоритм подписи по типу PEM-закодированного закрытого ключа, включая алгоритмы, у которых нет непосредственно экспонированных констант имён, например, 'ecdsa-with-SHA256'.
Пример: подписание с использованием ECDSA с SHA256
const crypto = require('crypto');
const sign = crypto.createSign('sha256');
sign.update('some data to sign');
const private_key = '-----BEGIN EC PRIVATE KEY-----\n' +
'MHcCAQEEIF+jnWY1D5kbVYDNvxxo/Y+ku2uJPDwS0r/VuPZQrjjVoAoGCCqGSM49\n' +
'AwEHoUQDQgAEurOxfSxmqIRYzJVagdZfMMSjRNNhB8i3mXyIMq704m2m52FdfKZ2\n' +
'pQhByd5eyj3lgZ7m7jbchtdgyOF8Io/1ng==\n' +
'-----END EC PRIVATE KEY-----\n';
console.log(sign.sign(private_key).toString('hex'));
sign.sign(private_key[, output_format])
Вычисляет подпись на всех данных, переданных с помощью sign.update() или sign.write().
Аргумент private_key может быть объектом или строкой. Если private_key является строкой, она обрабатывается как сырой ключ без парольной фразы. Если private_key — объект, он интерпретируется как объект, содержащий два свойства:
-
key: <Строка> — PEM-закодированный закрытый ключ -
passphrase: <Строка> — парольная фраза для закрытого ключа
output_format может указать один из 'binary', 'hex' или 'base64'. Если output_format предоставлен, возвращается строка; в противном случае возвращается Buffer.
Объект Sign нельзя использовать повторно после вызова метода sign.sign(). Несколько вызовов sign.sign() приведут к ошибке.
sign.update(data[, input_encoding])
Обновляет содержимое Sign с заданными data, кодировка которых указана в input_encoding и может быть 'utf8', 'ascii' или 'binary'. Если encoding не указан, и data — строка, используется кодировка 'utf8'. Если data — Buffer, то input_encoding игнорируется.
Это можно вызывать многократно с новыми данными по мере их поступления.
Класс: Verify
Класс Verify — это утилита для проверки подписей. Его можно использовать двумя способами:
- В качестве записываемого потока, где записанные данные используются для проверки против предоставленной подписи, или
- Используя методы
verify.update()иverify.verify()для проверки подписи.
Метод [crypto.createVerify()][] используется для создания экземпляров Verify. Экземпляры Verify не должны создаваться напрямую с помощью ключевого слова new.
Пример: Использование объектов Verify в качестве потоков:
const crypto = require('crypto');
const verify = crypto.createVerify('RSA-SHA256');
verify.write('some data to sign');
verify.end();
const public_key = getPublicKeySomehow();
const signature = getSignatureToVerify();
console.log(verify.verify(public_key, signature));
// Prints true or false
Пример: Использование методов verify.update() и verify.verify():
const crypto = require('crypto');
const verify = crypto.createVerify('RSA-SHA256');
verify.update('some data to sign');
const public_key = getPublicKeySomehow();
const signature = getSignatureToVerify();
console.log(verify.verify(public_key, signature));
// Prints true or false
verifier.update(data[, input_encoding])
Обновляет содержимое Verify заданным data, кодировка которого задана в input_encoding и может быть 'utf8', 'ascii' или 'binary'. Если encoding не указан, а data является строкой, используется кодировка 'utf8'. Если data является Buffer, то input_encoding игнорируется.
Это можно вызывать многократно с новыми данными по мере их потоковой передачи.
verifier.verify(object, signature[, signature_format])
Проверяет предоставленные данные с помощью заданного object и signature. Аргумент object — строка, содержащая PEM-закодированный объект, который может быть открытым ключом RSA, открытым ключом DSA или сертификатом X.509. Аргумент signature — предварительно вычисленная подпись данных в signature_format, которая может быть 'binary', 'hex' или 'base64'. Если указан signature_format, ожидается, что signature будет строкой; в противном случае ожидается, что signature будет Buffer.
Возвращает true или false в зависимости от валидности подписи для данных и открытого ключа.
Объект verifier не может быть использован повторно после вызова verify.verify(). Несколько вызовов verify.verify() приведут к ошибке.
crypto методы и свойства модуля
crypto.DEFAULT_ENCODING
Кодировка по умолчанию для функций, которые могут принимать строки или буферы. Значение по умолчанию — 'buffer', что делает методы по умолчанию объектами Buffer.
Механизм crypto.DEFAULT_ENCODING предоставлен для обратной совместимости со старыми программами, которые ожидают, что 'binary' будет кодировкой по умолчанию.
Новые приложения должны ожидать, что по умолчанию будет 'buffer'. Это свойство может быть устаревшим в будущих выпусках Node.js.
crypto.createCipher(algorithm, password)
Создает и возвращает объект Cipher, который использует заданный algorithm и password.
algorithm зависит от OpenSSL, примерами являются 'aes192', и т. д. В последних версиях OpenSSL openssl list-cipher-algorithms отобразит доступные алгоритмы шифрования.
password используется для вывода ключа шифрования и вектора инициализации (IV). Значение должно быть либо строкой, закодированной в 'binary', либо Buffer.
Реализация crypto.createCipher() выводит ключи, используя функцию OpenSSL EVP_BytesToKey с алгоритмом дайджеста MD5, одной итерацией и без соли. Отсутствие соли позволяет атакам по словарю, так как один и тот же пароль всегда создаёт один и тот же ключ. Низкое число итераций и некриптографически безопасный алгоритм хеширования позволяют очень быстро проверять пароли.
В соответствии с рекомендацией OpenSSL использовать pbkdf2 вместо EVP_BytesToKey, рекомендуется разработчикам самостоятельно выводить ключ и IV, используя crypto.pbkdf2(), и использовать crypto.createCipheriv() для создания объекта Cipher.
crypto.createCipheriv(algorithm, key, iv)
Создает и возвращает объект Cipher, с заданным algorithm, key и вектором инициализации (iv).
algorithm зависит от OpenSSL, примерами являются 'aes192', и т. д. В последних версиях OpenSSL openssl list-cipher-algorithms отобразит доступные алгоритмы шифрования.
key — это исходный ключ, используемый algorithm, а iv — вектор инициализации. Оба аргумента должны быть строками, закодированными в 'binary', или буферами.
crypto.createCredentials(details)
tls.createSecureContext() вместо этого.Метод crypto.createCredentials() — устаревший псевдоним для создания и возврата объекта tls.SecureContext. Метод crypto.createCredentials() не следует использовать.
Необязательный аргумент details — это объект хеша с ключами:
-
pfx: <String> | <Buffer> - PFX или PKCS12 закодированный закрытый ключ, сертификат и сертификаты CA -
key: <String> - PEM-закодированный закрытый ключ -
passphrase: <String> - пароль для закрытого ключа или PFX -
cert: <String> - PEM-закодированный сертификат -
ca: <String> | <Array> - либо строка, либо массив строк PEM-закодированных сертификатов CA для доверия. -
crl: <String> | <Array> - либо строка, либо массив строк PEM-закодированных CRL (Список отзыва сертификатов) -
ciphers: <String> использующий формат списка шифров OpenSSL, описывающий используемые или исключаемые алгоритмы шифрования.
Если детали 'ca' не указаны, Node.js будет использовать список публично доверенных CA по умолчанию Mozilla .
crypto.createDecipher(algorithm, password)
Создаёт и возвращает объект Decipher, который использует заданный algorithm и password (ключ).
Реализация crypto.createDecipher() выводит ключи, используя функцию OpenSSL EVP_BytesToKey с алгоритмом дайджеста MD5, одной итерацией и без соли. Отсутствие соли позволяет атакам по словарю, так как один и тот же пароль всегда создаёт один и тот же ключ. Низкое число итераций и некриптографически безопасный алгоритм хеширования позволяют очень быстро проверять пароли.
В соответствии с рекомендацией OpenSSL использовать pbkdf2 вместо EVP_BytesToKey, рекомендуется разработчикам самостоятельно выводить ключ и IV, используя crypto.pbkdf2(), и использовать crypto.createDecipheriv() для создания объекта Decipher.
crypto.createDecipheriv(algorithm, key, iv)
Создает и возвращает объект Decipher который использует заданный algorithm, key и вектор инициализации (iv).
algorithm зависит от OpenSSL, примерами являются 'aes192', и т. д. В последних версиях OpenSSL openssl list-cipher-algorithms отобразит доступные алгоритмы шифрования.
key — это исходный ключ, используемый algorithm, а iv — вектор инициализации. Оба аргумента должны быть строками, закодированными в 'binary', или буферами.
crypto.createDiffieHellman(prime[, prime_encoding][, generator][, generator_encoding])
Создаёт объект обмена ключами Диффи-Хеллмана, используя предоставленный prime и необязательный конкретный generator.
Аргумент generator может быть числом, строкой или Buffer. Если generator не указан, используется значение 2.
Аргументы prime_encoding и generator_encoding могут быть 'binary', 'hex' или 'base64'.
Если prime_encoding указан, ожидается, что prime будет строкой; в противном случае ожидается Buffer.
Если generator_encoding указан, ожидается, что generator будет строкой; в противном случае ожидается либо число, либо Buffer.
crypto.createDiffieHellman(prime_length[, generator])
Создаёт объект обмена ключами Диффи-Хеллмана и генерирует простое число длиной prime_length бит, используя необязательный конкретный числовой generator. Если generator не указан, используется значение 2.
crypto.createECDH(curve_name)
Создаёт объект обмена ключами Диффи-Хеллмана для эллиптических кривых (ECDH) используя предварительно определённую кривую, указанную в строке curve_name. Используйте crypto.getCurves(), чтобы получить список доступных имён кривых. В последних версиях OpenSSL, openssl ecparam -list_curves также отобразит имя и описание каждой доступной эллиптической кривой.
crypto.createHash(algorithm)
Создаёт и возвращает объект Hash, который можно использовать для генерации хеш-дайджестов с помощью указанного algorithm.
Выбор algorithm зависит от поддерживаемых алгоритмов, доступных в версии OpenSSL на платформе. Примерами являются 'sha256', 'sha512', и т. д. В последних версиях OpenSSL, openssl list-message-digest-algorithms отобразит доступные алгоритмы дайджестов.
Пример: генерация sha256 суммы файла
const filename = process.argv[2];
const crypto = require('crypto');
const fs = require('fs');
const hash = crypto.createHash('sha256');
const input = fs.createReadStream(filename);
input.on('readable', () => {
var data = input.read();
if (data)
hash.update(data);
else {
console.log(`${hash.digest('hex')} ${filename}`);
}
});
crypto.createHmac(algorithm, key)
Создаёт и возвращает объект Hmac использующий заданный algorithm и key.
Выбор algorithm зависит от поддерживаемых алгоритмов, доступных в версии OpenSSL на платформе. Примерами являются 'sha256', 'sha512', и т. д. В последних версиях OpenSSL, openssl list-message-digest-algorithms отобразит доступные алгоритмы дайджестов.
key — это ключ HMAC, используемый для генерации криптографического хеша HMAC.
Пример: генерация sha256 HMAC файла
const filename = process.argv[2];
const crypto = require('crypto');
const fs = require('fs');
const hmac = crypto.createHmac('sha256', 'a secret');
const input = fs.createReadStream(filename);
input.on('readable', () => {
var data = input.read();
if (data)
hmac.update(data);
else {
console.log(`${hmac.digest('hex')} ${filename}`);
}
});
crypto.createSign(algorithm)
Создаёт и возвращает объект Sign, использующий указанный algorithm . Используйте crypto.getHashes() для получения массива имён доступных алгоритмов подписи.
crypto.createVerify(algorithm)
Создаёт и возвращает объект Verify, использующий заданный алгоритм. Используйте crypto.getHashes() для получения массива имён доступных алгоритмов подписи.
crypto.getCiphers()
Возвращает массив с именами поддерживаемых алгоритмов шифрования.
Пример:
const ciphers = crypto.getCiphers(); console.log(ciphers); // ['aes-128-cbc', 'aes-128-ccm', ...]
crypto.getCurves()
Возвращает массив с именами поддерживаемых эллиптических кривых.
Пример:
const curves = crypto.getCurves(); console.log(curves); // ['secp256k1', 'secp384r1', ...]
crypto.getDiffieHellman(group_name)
Создаёт предопределённый объект обмена ключами DiffieHellman . Поддерживаемые группы: 'modp1', 'modp2', 'modp5' (определены в RFC 2412, но см. Предостережения) и 'modp14', 'modp15', 'modp16', 'modp17', 'modp18' (определены в RFC 3526). Возвращаемый объект имитирует интерфейс объектов, созданных с помощью crypto.createDiffieHellman(), но не позволит изменять ключи (например, с помощью diffieHellman.setPublicKey()). Преимущество использования этого метода заключается в том, что сторонам не нужно предварительно генерировать или обмениваться модулем группы, что экономит процессорное время и время связи.
Пример (получение общего секрета):
const crypto = require('crypto');
const alice = crypto.getDiffieHellman('modp14');
const bob = crypto.getDiffieHellman('modp14');
alice.generateKeys();
bob.generateKeys();
const alice_secret = alice.computeSecret(bob.getPublicKey(), null, 'hex');
const bob_secret = bob.computeSecret(alice.getPublicKey(), null, 'hex');
/* alice_secret and bob_secret should be the same */
console.log(alice_secret == bob_secret);
crypto.getHashes()
Возвращает массив имён поддерживаемых алгоритмов хеширования, таких как RSA-SHA256.
Пример:
const hashes = crypto.getHashes(); console.log(hashes); // ['sha', 'sha1', 'sha1WithRSAEncryption', ...]
crypto.pbkdf2(password, salt, iterations, keylen[, digest], callback)
Предоставляет асинхронную реализацию функции вывода ключа парольной базы данных 2 (PBKDF2). Указанный алгоритм HMAC дайджеста digest применяется для вывода ключа требуемой длины в байтах (keylen) из password, salt и iterations. Если алгоритм digest не указан, используется значение по умолчанию 'sha1'.
Поставленная функция callback вызывается с двумя аргументами: err и derivedKey. Если произошла ошибка, err будет установлено; в противном случае err будет равно null. Успешно сгенерированный derivedKey будет передан в виде Buffer.
Аргумент iterations должен быть числом, установленным как можно выше. Чем выше число итераций, тем безопаснее полученный ключ, но потребуется больше времени для завершения.
Аргумент salt также должен быть максимально уникальным. Рекомендуется, чтобы соли были случайными и их длина превышала 16 байт. См. NIST SP 800-132 для получения подробной информации.
Пример:
const crypto = require('crypto');
crypto.pbkdf2('secret', 'salt', 100000, 512, 'sha512', (err, key) => {
if (err) throw err;
console.log(key.toString('hex')); // 'c5e478d...1469e50'
});
Массив поддерживаемых функций дайджеста можно получить, используя crypto.getHashes().
crypto.pbkdf2Sync(password, salt, iterations, keylen[, digest])
Предоставляет синхронную реализацию функции вывода ключа парольной базы данных 2 (PBKDF2). Указанный алгоритм HMAC дайджеста digest применяется для вывода ключа требуемой длины в байтах (keylen) из password, salt и iterations. Если алгоритм digest не указан, используется значение по умолчанию 'sha1'.
Если произошла ошибка, будет выброшено исключение Error, в противном случае полученный ключ будет возвращён в виде Buffer.
Аргумент iterations должен быть числом, установленным как можно выше. Чем выше число итераций, тем безопаснее полученный ключ, но потребуется больше времени для завершения.
Аргумент salt также должен быть максимально уникальным. Рекомендуется, чтобы соли были случайными и их длина превышала 16 байт. См. NIST SP 800-132 для получения подробной информации.
Пример:
const crypto = require('crypto');
const key = crypto.pbkdf2Sync('secret', 'salt', 100000, 512, 'sha512');
console.log(key.toString('hex')); // 'c5e478d...1469e50'
Массив поддерживаемых функций дайджеста можно получить, используя crypto.getHashes().
crypto.privateDecrypt(private_key, buffer)
Расшифровывает buffer с использованием private_key.
private_key может быть объектом или строкой. Если private_key — строка, она обрабатывается как ключ без пароля и используется RSA_PKCS1_OAEP_PADDING. Если private_key — объект, он интерпретируется как объект хеша с ключами:
-
key: <Строка> — PEM-кодированный закрытый ключ -
passphrase: <Строка> — необязательный пароль для закрытого ключа -
padding: Необязательное значение заполнения, одно из следующих:constants.RSA_NO_PADDINGconstants.RSA_PKCS1_PADDINGconstants.RSA_PKCS1_OAEP_PADDING
Все виды заполнения определены в модуле constants.
crypto.privateEncrypt(private_key, buffer)
Шифрует buffer с использованием private_key.
private_key может быть объектом или строкой. Если private_key — строка, она обрабатывается как ключ без пароля и используется RSA_PKCS1_PADDING. Если private_key — объект, он интерпретируется как объект хеша с ключами:
-
key: <Строка> — PEM-кодированный закрытый ключ -
passphrase: <Строка> — необязательный пароль для закрытого ключа -
padding: Необязательное значение заполнения, одно из следующих:constants.RSA_NO_PADDINGconstants.RSA_PKCS1_PADDING
Все виды заполнения определены в модуле constants.
crypto.publicDecrypt(public_key, buffer)
Расшифровывает buffer с использованием public_key.
public_key может быть объектом или строкой. Если public_key — строка, она обрабатывается как ключ без пароля и используется RSA_PKCS1_PADDING. Если public_key — объект, он интерпретируется как объект хеша с ключами:
-
key: <Строка> — PEM-кодированный открытый ключ -
passphrase: <Строка> — необязательный пароль для закрытого ключа -
padding: Необязательное значение заполнения, одно из следующих:constants.RSA_NO_PADDINGconstants.RSA_PKCS1_PADDINGconstants.RSA_PKCS1_OAEP_PADDING
Поскольку открытые ключи RSA могут быть получены из закрытых ключей, вместо открытого ключа может быть передан закрытый ключ.
Все виды заполнения определены в модуле constants.
crypto.publicEncrypt(public_key, buffer)
Шифрует buffer с использованием public_key.
public_key может быть объектом или строкой. Если public_key является строкой, она обрабатывается как ключ без парольной фразы и использует RSA_PKCS1_OAEP_PADDING. Если public_key является объектом, он интерпретируется как объект хеша с ключами:
-
key: <Строка> - PEM-кодированный открытый ключ -
passphrase: <Строка> - Необязательная парольная фраза для закрытого ключа -
padding: Необязательное значение заполнения, одно из следующих:constants.RSA_NO_PADDINGconstants.RSA_PKCS1_PADDINGconstants.RSA_PKCS1_OAEP_PADDING
Поскольку открытые ключи RSA могут быть получены из закрытых ключей, вместо открытого ключа можно передать закрытый ключ.
Все значения заполнения определены в модуле constants.
crypto.randomBytes(size[, callback])
Генерирует криптографически стойкие псевдослучайные данные. Аргумент size — число, указывающее количество байтов для генерации.
Если функция callback предоставлена, байты генерируются асинхронно, и функция callback вызывается с двумя аргументами: err и buf. Если произошла ошибка, err будет объектом Error; в противном случае он равен null. Аргумент buf — Buffer, содержащий сгенерированные байты.
// Asynchronous
const crypto = require('crypto');
crypto.randomBytes(256, (err, buf) => {
if (err) throw err;
console.log(`${buf.length} bytes of random data: ${buf.toString('hex')}`);
});
Если функция callback не предоставлена, случайные байты генерируются синхронно и возвращаются как Buffer. Ошибка будет выброшена, если возникнет проблема с генерацией байтов.
// Synchronous
const buf = crypto.randomBytes(256);
console.log(
`${buf.length} bytes of random data: ${buf.toString('hex')}`);
Метод crypto.randomBytes() будет блокироваться до тех пор, пока не будет достаточно энтропии. Обычно это занимает не более нескольких миллисекунд. Единственный случай, когда генерация случайных байтов может занять более длительное время, — сразу после загрузки системы, когда вся система всё ещё имеет недостаточно энтропии.
crypto.setEngine(engine[, flags])
Загружает и устанавливает engine для некоторых или всех функций OpenSSL (выбираемых флагами).
engine может быть либо идентификатором, либо путём к библиотеке общих функций двигателя.
Необязательный аргумент flags использует ENGINE_METHOD_ALL по умолчанию. Аргумент flags — битовое поле, принимающее одно или несколько из следующих флагов (определённых в модуле constants):
ENGINE_METHOD_RSAENGINE_METHOD_DSAENGINE_METHOD_DHENGINE_METHOD_RANDENGINE_METHOD_ECDHENGINE_METHOD_ECDSAENGINE_METHOD_CIPHERSENGINE_METHOD_DIGESTSENGINE_METHOD_STOREENGINE_METHOD_PKEY_METHENGINE_METHOD_PKEY_ASN1_METHENGINE_METHOD_ALLENGINE_METHOD_NONE
Примечания
API потоков legacy (до Node.js v0.10)
Модуль Crypto был добавлен в Node.js до появления концепции унифицированного API потоков и до появления объектов Buffer для обработки двоичных данных. В связи с этим многие из классов crypto, определённые классы, имеют методы, которые нетипичны для других классов Node.js, реализующих API потоков streams (например, update(), final(), или digest()). Кроме того, многие методы принимали и возвращали 'binary' кодированные строки по умолчанию, а не Buffers. Этот дефолт был изменён после Node.js v0.8 на использование объектов Buffer по умолчанию.
Недавние изменения в ECDH
Использование ECDH с нединамически сгенерированными парами ключей упрощено. Теперь ecdh.setPrivateKey() может быть вызвано с предварительно выбранным закрытым ключом, и соответствующая точка (ключ) будет вычислена и сохранена в объекте. Это позволяет коду хранить и предоставлять только закрытую часть пары ключей EC. ecdh.setPrivateKey() теперь также проверяет, что закрытый ключ действителен для выбранной кривой.
Метод ecdh.setPublicKey() теперь устарел, так как его включение в API не имеет практического смысла. Должно быть установлено ранее сохранённое значение закрытого ключа, которое автоматически генерирует соответствующий открытый ключ, или должен быть вызван ecdh.generateKeys(). Основным недостатком использования ecdh.setPublicKey() является то, что он может привести к несогласованному состоянию пары ключей ECDH.
Поддержка слабых или скомпрометированных алгоритмов
Модуль crypto по-прежнему поддерживает некоторые алгоритмы, которые уже скомпрометированы и в настоящее время не рекомендуются для использования. API также позволяет использовать шифры и хеши с небольшим размером ключа, которые считаются слишком слабыми для безопасного использования.
Пользователи несут полную ответственность за выбор алгоритма шифрования и размера ключа в соответствии со своими требованиями безопасности.
В соответствии с рекомендациями NIST SP 800-131A:
- MD5 и SHA-1 больше не приемлемы там, где требуется стойкость к коллизиям, например, в цифровых подписях.
- Для безопасного использования в течение нескольких лет рекомендуется использовать ключ с алгоритмами RSA, DSA и DH размером не менее 2048 бит, а кривые ECDSA и ECDH — не менее 224 бит.
- Группы DH
modp1,modp2иmodp5имеют размер ключа меньше 2048 бит и не рекомендуются.
См. справку для получения других рекомендаций и подробностей.
© Joyent, Inc. and other Node contributors
Licensed under the MIT License.
Node.js is a trademark of Joyent, Inc. and is used with its permission.
We are not endorsed by or affiliated with Joyent.
https://nodejs.org/dist/latest-v4.x/docs/api/crypto.html