🔥Боевая серия Nodejs: шифрование данных и криптомодуль

Node.js

адрес блога:"Исследование модуля 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 в приложениях блокчейна. Эта статья больше не записывается, и заинтересованные студенты могут перейти к соответствующей информации.

Ссылка на ссылку

👇Отсканируйте код, чтобы следовать"Блог сердечного загара", проверьте «Внешний график» и «Алгоритм решения проблем», настаивайте на совместном использовании и развивайтесь вместе👇