Шифрование данных с помощью открытого ключа в node.js
Мне нужно зашифровать строку, используя открытый ключ (файл pem), а затем подписать его с помощью закрытого ключа (также pem).
Я загружаю файлы pem отлично:
publicCert = fs.readFileSync(publicCertFile).toString();
но после нескольких часов очистки google я не могу найти способ шифрования данных с помощью открытого ключа. В php я просто вызываю openssl_public_encrypt, но я не вижу никакой соответствующей функции в node или в любых модулях.
Если у кого есть какие-либо предложения, сообщите мне.
Ответы
Ответ 1
Нет необходимых друзей для библиотеки,
Введите crypto
Здесь janky маленький модуль, который вы могли бы использовать для шифрования/дешифрования строк с помощью ключей RSA:
var crypto = require("crypto");
var path = require("path");
var fs = require("fs");
var encryptStringWithRsaPublicKey = function(toEncrypt, relativeOrAbsolutePathToPublicKey) {
var absolutePath = path.resolve(relativeOrAbsolutePathToPublicKey);
var publicKey = fs.readFileSync(absolutePath, "utf8");
var buffer = new Buffer(toEncrypt);
var encrypted = crypto.publicEncrypt(publicKey, buffer);
return encrypted.toString("base64");
};
var decryptStringWithRsaPrivateKey = function(toDecrypt, relativeOrAbsolutePathtoPrivateKey) {
var absolutePath = path.resolve(relativeOrAbsolutePathtoPrivateKey);
var privateKey = fs.readFileSync(absolutePath, "utf8");
var buffer = new Buffer(toDecrypt, "base64");
var decrypted = crypto.privateDecrypt(privateKey, buffer);
return decrypted.toString("utf8");
};
module.exports = {
encryptStringWithRsaPublicKey: encryptStringWithRsaPublicKey,
decryptStringWithRsaPrivateKey: decryptStringWithRsaPrivateKey
}
Я бы рекомендовал не использовать синхронные методы fs, где это возможно, и вы могли бы использовать Promises, чтобы сделать это лучше, но для простых случаев использования это подход, который я видел в работе, и возьму
Ответ 2
Обновленный общедоступный/частный модуль расшифровки и шифрования - URSA. Модуль node -rsa устарел.
Этот модуль Node предоставляет довольно полный набор оберток для Скриптовая функциональность OpenSSL с открытым/закрытым ключом RSA.
npm install ursa
Смотрите: https://github.com/Obvious/ursa
Ответ 3
Как насчет этого node -rsa module? Здесь ссылка на test.js файл, демонстрирующий использование.
Ответ 4
TL; DR: Урса - ваш лучший выбор. Его действительно фанки, что это не стандартно с криптографией node.
Все другие найденные мной решения либо не работают в Windows, либо фактически не являются библиотеками шифрования. Урса, рекомендованная Луи, выглядит лучше всего. Если вы не заботитесь о окнах, вы еще более золотистые. Обратите внимание на Ursa, мне нужно было установить Open SSL вместе с тем, что называется "Распространяемые материалы Visual С++ 2008", чтобы заставить работу npm работать. Получите этот хлам здесь: http://slproweb.com/products/Win32OpenSSL.html
Пробой:
- Раздражающие дополнительные шаги по установке вручную для окон
- Не совместим с окнами
- Не библиотеки шифрования
Это буквально все, что я мог найти.
Ответ 5
Это не поддерживается на основе node версии v0.11.13 или ниже, но похоже, что следующая версия node (a.k.a v0.12) будет поддерживать это.
Вот ключ: https://github.com/joyent/node/blob/v0.12/lib/crypto.js#L358
см. crypto.publicEncrypt
и crypto.privateDecrypt
Вот будущая документация для этого
https://github.com/joyent/node/blob/7c0419730b237dbfa0ec4e6fb33a99ff01825a8f/doc/api/crypto.markdown#cryptopublicencryptpublic_key-buffer
Ответ 6
Я проверил это в Node 10, вы можете использовать функции шифрования/дешифрования (небольшие изменения в ответе Джейкоба)
const crypto = require('crypto')
const path = require('path')
const fs = require('fs')
function encrypt(toEncrypt, relativeOrAbsolutePathToPublicKey) {
const absolutePath = path.resolve(relativeOrAbsolutePathToPublicKey)
const publicKey = fs.readFileSync(absolutePath, 'utf8')
const buffer = Buffer.from(toEncrypt, 'utf8')
const encrypted = crypto.publicEncrypt(publicKey, buffer)
return encrypted.toString('base64')
}
function decrypt(toDecrypt, relativeOrAbsolutePathtoPrivateKey) {
const absolutePath = path.resolve(relativeOrAbsolutePathtoPrivateKey)
const privateKey = fs.readFileSync(absolutePath, 'utf8')
const buffer = Buffer.from(toDecrypt, 'base64')
const decrypted = crypto.privateDecrypt(
{
key: privateKey.toString(),
passphrase: '',
},
buffer,
)
return decrypted.toString('utf8')
}
const enc = encrypt('hello', 'public.pem')
console.log('enc', enc)
const dec = decrypt(enc, 'private.pem')
console.log('dec', dec)
Для ключей вы можете сгенерировать их с
const { writeFileSync } = require('fs')
const { generateKeyPairSync } = require('crypto')
function generateKeys() {
const { privateKey, publicKey } = generateKeyPairSync('rsa', {
modulusLength: 4096,
publicKeyEncoding: {
type: 'pkcs1',
format: 'pem',
},
privateKeyEncoding: {
type: 'pkcs1',
format: 'pem',
cipher: 'aes-256-cbc',
passphrase: '',
},
})
writeFileSync('private.pem', privateKey)
writeFileSync('public.pem', publicKey)
}