NodeJS загружает сертификат PFX из файла
Я пишу небольшой проект с использованием Node.JS и TypeScript, одна из требований - прочитать сертификат PFX из файла.pfx и использовать его в коде для шифрования тела полезной нагрузки.
У меня есть файл сертификата открытого / закрытого ключа cert1.pfx
мой код требует этот сертификат, как показано ниже
...
const cert = loadPfx("cert1.pfx");
const p: Payload = new Payload();
p.addReaderCertificate(cert);
...
Я искал вокруг, но не могу найти способ загрузить PFX для моего варианта использования, я видел примеры загрузки PFX для HTTPS-сервера или Express.JS, я смотрел node-x509, но это для сертификатов CER или PEM в кодировке BASE64 Я также посмотрел на node-rsa, но это для шифрования / дешифрования с использованием открытых / закрытых ключей.
Кто-нибудь знает возможно ли это? Если это так, буду признателен за некоторые советы о том, как достичь.
5 ответов
Поэтому после МНОГО исследований и траления в архивах Google я наткнулся на пакет под названием pem
и это имеет следующий метод:
pem.readPkcs12(bufferOrPath, [options], callback)
Это может прочитать файл PKCS#12 (или другими словами *.pfx
или же *.p12
файл) среди прочего, я, должно быть, пропустил это в моих предыдущих исследованиях.
Использование:
const pem = require("pem");
const fs = require("fs");
const pfx = fs.readFileSync(__dirname + "/test.pfx");
pem.readPkcs12(pfx, { p12Password: "password" }, (err, cert) => {
console.log(cert);
});
Выход:
{ cert: "...", ca: ["subca", "rootca"], key: "..." }
Похоже, вам нужно использовать только собственные возможности Node по протоколу https. Node может читать файл PFX напрямую. ( Https.createServer, Параметры SSL)
Пример с сайта Node.js:
const https = require('https');
const fs = require('fs');
const options = {
pfx: fs.readFileSync('test/fixtures/test_cert.pfx'),
passphrase: 'sample'
};
https.createServer(options, (req, res) => {
res.writeHead(200);
res.end('hello world\n');
}).listen(8000);
Я также застрял на аналогичной проблеме. Решение @neil-stevens помогло мне прочитать файл.pfx, но я обнаружил одну функцию / ошибку (я точно не знаю, что это такое) pem, которая в основном возвращает зашифрованный закрытый ключ в RSA, но если вам нужен реальный закрытый ключ, вам нужно экспортировать зашифрованный ключ в pkcs8, что можно сделать с помощью Node RSA.
Применение:
const RSAKey = cert.key;
const key = new NodeRSA(RSAKey);
const privateKey = key.exportKey("pkcs8");
Я прибыл сюда, пытаясь найти способ настроить локальный веб-сервер с HTTPS для локальной разработки с использованием сертификата разработки, сгенерированного .NET CLI (поскольку его легко создать/доверить/удалить).
Благодаря ответу Нила Стивена я смог создать рабочее решение для Windows, используя комбинацию npm,
dotnet
интерфейс командной строки,
openssl
и пакет npm
pem
.
Git
поставляется с копией OpenSSL, поэтому мне не нужно было устанавливать его отдельно :)
.env
OPENSSL_PATH=C:\Program Files\Git\usr\bin\openssl
CERT_PASSWORD=SecurePassword123
CERT_PFX=cert/localhost.pfx
CERT_PEM=cert/localhost.pem
CERT_KEY=cert/localhost.key
PORT=443
ENTRYPOINT=src/index.html
пакет.json
"scripts": {
"start": "env-cmd -x parcel $ENTRYPOINT --https --cert $CERT_PEM --key $CERT_KEY --port $PORT --open",
"build": "env-cmd -x parcel build $ENTRYPOINT",
"dev-certs": "run-s dev-certs:create dev-certs:convert",
"dev-certs:create": "env-cmd -x dotnet dev-certs https -ep $CERT_PFX -p $CERT_PASSWORD --verbose --trust",
"dev-certs:convert": "node ./cli/cert.mjs",
"dev-certs:clean": "dotnet dev-certs https --clean"
},
сертификат.mjs
import pem from "pem";
import { PFX2PEM } from "pem/lib/convert.js";
import fs from "fs";
import "dotenv/config";
pem.config({
pathOpenSSL: process.env.OPENSSL_PATH
});
const pass = process.env.CERT_PASSWORD;
// GET .KEY FILE - without this, HMR won't work
const pfx = fs.readFileSync(process.env.CERT_PFX);
pem.readPkcs12(pfx, { p12Password: pass }, (err, cert) => {
if (!!err) {
console.error(err);
return;
}
// console.log(cert.key);
fs.writeFileSync(process.env.CERT_KEY, cert.key);
});
// GET .PEM FILE
PFX2PEM(process.env.CERT_PFX, process.env.CERT_PEM, pass, (errPem, successPem) => {
if (!successPem) {
console.error(errPem);
return;
}
console.log(`Certificate '${process.env.CERT_PEM}' created!`);
});
Репозиторий находится здесь: https://github.com/zplume/parcel-https и
README
содержит подробную информацию о том, как это работает.
Дополняя ответ Нила Стивенса (извините, не знаю, как цитировать).
- У меня была проблема с получением только пустого объекта, но я просто заметил, что не регистрировал ошибку . Так что я сделал это, после этого я смог решить свои проблемы
1º Вам необходимо установить openSSL или libressl, как описано на https://github.com/Dexus/pem.
- Совет: Для установки, если вы уже настроили и установили Chocolatey. Просто запустите команду: «choco install openssl». (с повышенными правами)
2º Мне пришлось использовать pem.config(), чтобы установить точный путь к папке openSSL. Я думаю, вы также можете определить переменные среды, я просто еще не тестировал этот способ.
3º Наконец, мой код остался таким:
const pem = require("pem");
const fs = require("fs");
const pfx = fs.readFileSync("./cert.pfx");
let certificate = '';
pem.config({
pathOpenSSL: 'C:\\Program Files\\OpenSSL-Win64\\bin\\openssl'
})
const getPrivateKey = async () => {
return new Promise(async (resolve, reject) => {
pem.readPkcs12(pfx, { p12Password: 'myPassWordStr' }, (err, cert) => {
console.log('err::: ', err);
// console.log('cert::: ', cert);
resolve(cert);
});
});
}
const start = async () => {
certificate = await getPrivateKey();
console.log('privateKey::: ', certificate);
}
start();