адрес блога:"Исследование модуля NodeJS - крипто"
Гитхаб:GitHub.com/Дунъюаньсинь…
Модуль crypto в nodejs предоставляет API для различных алгоритмов шифрования. В этой статье описаны типы, характеристики, использование и реализации кода широко используемых алгоритмов шифрования. Среди них есть множество алгоритмов и широких областей применения, и каждый тип алгоритма имеет свои применимые сценарии. Чтобы сделать запись гладкой, перечислено несколько распространенных алгоритмов, записанных в этой статье:
- Краткое содержание: Алгоритм хеширования
- Краткое содержание: Алгоритм HMac
- Шифрование и дешифрование контента: симметричное шифрование (AES) и асимметричное шифрование и дешифрование (RSA)
- Подписание контента: алгоритмы подписи и проверки
Хэш-алгоритм
Хеш-функция, также известная как хеш-алгоритм или хеш-функция, представляет собой метод создания небольшого цифрового «отпечатка пальца» из любых данных. Основной принцип заключается в том, чтобы вводить данные произвольной длины и, наконец, выводить результат фиксированной длины.
Алгоритм хеширования имеет следующие характеристики:
- Исходные данные не могут быть отменены из хеш-значения
- Разный ввод, разный вывод
- Хороший алгоритм хеширования имеет более низкую вероятность коллизии
Из-за этих характеристик алгоритма хеширования алгоритм хеширования в основном используется для: шифрования, проверки данных, идентификации версии, балансировки нагрузки и распределенного (непротиворечивого хеширования).
Следующее реализует функцию для получения идентификатора файла:
const crypto = require("crypto");
const fs = require("fs");
function getFileHash(file, algorithm) {
if (!crypto.getHashes().includes(algorithm)) {
throw new Error("不支持此哈希函数");
}
return new Promise(resolve => {
const hash = crypto.createHash(algorithm);
const rs = fs.createReadStream(file);
rs.on("readable", () => {
const data = rs.read();
if (data) {
hash.update(data);
}
});
rs.on("end", () => {
resolve(hash.digest("hex"));
});
});
}
// 用法:获取文件md5
getFileHash("./db.json", "md5").then(val => {
console.log(val);
});
Алгоритм HMac
Злоумышленники могут использовать «радужные таблицы» для взлома хеш-таблиц. Способ работы с радужной таблицей состоит в том, чтобы добавить соль к паролю и использовать pwd и соль вместе для вычисления хеш-значения. Среди них соль генерируется случайным образом, чем дольше, тем лучше, и ее необходимо хранить в таблице данных, соответствующей имени пользователя и паролю.
Хотя расширение длины хеша достигается путем добавления соли, злоумышленник может взломать атаку, отправив пароль и значение HASH. Сервер сделает отправленный пароль и соль представляют собой строку, а затем сравните представленное значение HASH. Если система не может представить хеш-значение, он не будет предметом таких атак.
Очевидно, что нет абсолютно безопасного способа. Но соление пароля не рекомендуется, но алгоритм HMAC. Он может использовать произвольные хеш-функции, такие как MD5 => HMACMD5, SHA1 => HMACSHA1.
Ниже приведена функция для реализации зашифрованных данных с помощью Hmac:
const crypto = require("crypto");
function encryptData(data, key, algorithm) {
if (!crypto.getHashes().includes(algorithm)) {
throw new Error("不支持此哈希函数");
}
const hmac = crypto.createHmac(algorithm, key);
hmac.update(data);
return hmac.digest("hex");
}
// output: 30267bcf2a476abaa9b9a87dd39a1f8d6906d1180451abdcb8145b384b9f76a5
console.log(encryptData("root", "7(23y*&745^%I", "sha256"));
Симметричное шифрование (AES) и асимметричное шифрование и дешифрование (RSA)
Существует много данных, которые необходимо хранить в зашифрованном виде и расшифровывать для использования. Это отличается от предыдущей необратимой хеш-функции. Такие алгоритмы делятся на две категории:
- Симметричное шифрование (AES): для шифрования и дешифрования используется один и тот же ключ.
- Асимметричное шифрование и дешифрование (RSA): шифрование с открытым ключом, дешифрование с закрытым ключом
Симметричное шифрование (AES)
Посмотреть все алгоритмы шифрования, поддерживаемые nodejs:
crypto.getCiphers();
Nodejs предоставляет классы Cipher и Decipher для шифрования и дешифрования соответственно. Оба наследуются от Transfrom Stream, а использование API похоже на использование хеш-функции.
Далее следует зашифровать открытый текст с помощью алгоритма aes-256-cbc:
const crypto = require("crypto");
const secret = crypto.randomBytes(32); // 密钥
const content = "hello world!"; // 要加密的明文
const cipher = crypto.createCipheriv(
"aes-256-cbc",
secret,
Buffer.alloc(16, 0)
);
cipher.update(content, "utf8");
// 加密后的结果:e2a927165757acc609a89c093d8e3af5
console.log(cipher.final("hex"));
Уведомление: При использовании алгоритма шифрования необходима заданная длина ключа, иначе он лопнетthis[kHandle].initiv(cipher, credential, iv, authTagLength); Error: Invalid key length...
ошибка. Взяв в качестве примера алгоритм aes-256-cbc, требуется ключ размером 256 бит = 32 байта. Точно так же требуется IV AES, требующий 128 бит. (Пожалуйста, обратитесь к разделу «Справочные ссылки»)
Используйте 32 последовательныхI
В качестве ключа результатом, зашифрованным с помощью aes-256-cbc, является a061e67f5643d948418fdb150745f24d. Далее идет обратный процесс расшифровки:
const secret = "I".repeat(32);
const decipher = crypto.createDecipheriv(
"aes-256-cbc",
secret,
Buffer.alloc(16, 0)
);
decipher.update("a061e67f5643d948418fdb150745f24d", "hex");
console.log(decipher.final("utf8")); // 解密后的结果:hello world!
Асимметричное шифрование и дешифрование (RSA)
Сгенерируйте закрытый и открытый ключи с помощью openssl:
# 生成私钥
openssl genrsa -out privatekey.pem 1024
# 生成公钥
openssl rsa -in privatekey.pem -pubout -out publickey.pem
правильноhello world!
Код для шифрования и дешифрования выглядит следующим образом:
const crypto = require("crypto");
const fs = require("fs");
const privateKey = fs.readFileSync("./privatekey.pem");
const publicKey = fs.readFileSync("./publickey.pem");
const content = "hello world!"; // 待加密的明文内容
// 公钥加密
const encodeData = crypto.publicEncrypt(publicKey, Buffer.from(content));
console.log(encodeData.toString("base64"));
// 私钥解密
const decodeData = crypto.privateDecrypt(privateKey, encodeData);
console.log(decodeData.toString("utf8"));
Алгоритмы подписи и проверки
В дополнение к необратимым алгоритмам хеширования и алгоритмам шифрования данных существуют также алгоритмы, предназначенные для подписи и проверки. Здесь вам также нужно использовать openssl для генерации открытых и закрытых ключей.
Пример кода выглядит следующим образом:
const crypto = require("crypto");
const fs = require("fs");
const assert = require("assert");
const privateKey = fs.readFileSync("./privatekey.pem");
const publicKey = fs.readFileSync("./publickey.pem");
const data = "传输的数据";
// 第一步:用私钥对传输的数据,生成对应的签名
const sign = crypto.createSign("sha256");
// 添加数据
sign.update(data, "utf8");
sign.end();
// 根据私钥,生成签名
const signature = sign.sign(privateKey, "hex");
// 第二步:借助公钥验证签名的准确性
const verify = crypto.createVerify("sha256");
verify.update(data, "utf8");
verify.end();
assert.ok(verify.verify(publicKey, signature, "hex"));
Как видно из предыдущего кода, закрытый ключ используется для шифрования для получения значения подписи, а открытый ключ используется для проверки.
Суммировать
Раньше это всегда было наполовину понято, некоторые понятия очень расплывчаты, а алгоритмы хеширования и алгоритмы шифрования часто путают. Закончив эту заметку, я разобрался в функциях и использовании распространенных алгоритмов шифрования.
В дополнение к этому, модуль шифрования также предоставляет другие алгоритмические инструменты, такие как ECDH в приложениях блокчейна. Эта статья больше не записывается, и заинтересованные студенты могут перейти к соответствующей информации.
Ссылка на ссылку
- NodeJS docs: crypto
- Рекомендуется: библиотека алгоритмов шифрования Node.js Crypto
- Рекомендация: что такое хэш? - Ответы от Tencent Technology Engineering - Зная
- Вики: хэш-функции
- Store and validate hashed password
- Вики: Радужный стол
- Nodejs 6.10.2 crypto AES Invalid key length
- Encrypting using AES-256, can I use 256 bits IV?
- Крипто-шифрование и дешифрование
👇Отсканируйте код, чтобы следовать"Блог сердечного загара", проверьте «Внешний график» и «Алгоритм решения проблем», настаивайте на совместном использовании и развивайтесь вместе👇