J'ai commencé à écrire un wrapper pour une API qui requiert que toutes les demandes soient via HTTPS. Au lieu de faire des demandes à l'API réelle pendant que je développe et teste celle-ci, j'aimerais exécuter mon propre serveur localement, qui se moque des réponses.
Je ne comprends pas comment générer les certificats dont j'ai besoin pour créer un serveur HTTPS et lui envoyer des demandes.
Mon serveur ressemble à ceci:
var options = {
key: fs.readFileSync('./key.pem'),
cert: fs.readFileSync('./cert.pem')
};
https.createServer(options, function(req, res) {
res.writeHead(200);
res.end('OK\n');
}).listen(8000);
Les fichiers pem ont été générés avec:
openssl genrsa 1024 > key.pem
openssl req -x509 -new -key key.pem > cert.pem
Et une demande ressemble à ceci:
var options = {
Host: 'localhost',
port: 8000,
path: '/api/v1/test'
};
https.request(options, function(res) {
res.pipe(process.stdout);
}).end();
Avec cette configuration, je reçois Error: DEPTH_ZERO_SELF_SIGNED_CERT
, je pense donc avoir besoin d’ajouter une option ca
pour la requête.
Ma question est donc de savoir comment générer les éléments suivants:
key
?cert
?ca
pour la demande?J'ai lu quelques informations sur la génération de certificats auto-signés avec openssl, mais je n'arrive pas à comprendre ce qui se passe et à déterminer les clés et les certificats à utiliser dans le code de mon nœud.
Mise à jour
L'API fournit un certificat de CA à utiliser à la place des valeurs par défaut. Le code suivant fonctionne avec leur certificat et c’est ce que je veux reproduire localement.
var ca = fs.readFileSync('./certificate.pem');
var options = {
Host: 'example.com',
path: '/api/v1/test',
ca: ca
};
options.agent = new https.Agent(options);
https.request(options, function(res) {
res.pipe(process.stdout);
}).end();
Ou de vrais certificats feraient-ils le travail mieux? Avez-vous considéré l'un de ces?
(Remarque: Encrypt peut également émettre des certificats vers des réseaux privés)
https://coolaj86.com/articles/how-to-create-a-csr-for-https-tls-ssl-rsa-pems/
https://github.com/coolaj86/nodejs-self-signed-certificate-example
En utilisant localhost.greenlock.domains
_ à titre d'exemple (il pointe vers 127.0.0.1):
'use strict';
var https = require('https')
, port = process.argv[2] || 8043
, fs = require('fs')
, path = require('path')
, server
, options
;
require('ssl-root-cas')
.inject()
.addFile(path.join(__dirname, 'server', 'my-private-root-ca.cert.pem'))
;
options = {
// this is ONLY the PRIVATE KEY
key: fs.readFileSync(path.join(__dirname, 'server', 'privkey.pem'))
// You DO NOT specify `ca`, that's only for peer authentication
//, ca: [ fs.readFileSync(path.join(__dirname, 'server', 'my-private-root-ca.cert.pem'))]
// This should contain both cert.pem AND chain.pem (in that order)
, cert: fs.readFileSync(path.join(__dirname, 'server', 'fullchain.pem'))
};
function app(req, res) {
res.setHeader('Content-Type', 'text/plain');
res.end('Hello, encrypted world!');
}
server = https.createServer(options, app).listen(port, function () {
port = server.address().port;
console.log('Listening on https://127.0.0.1:' + port);
console.log('Listening on https://' + server.address().address + ':' + port);
console.log('Listening on https://localhost.greenlock.domains:' + port);
});
'use strict';
var https = require('https')
, fs = require('fs')
, path = require('path')
, ca = fs.readFileSync(path.join(__dirname, 'client', 'my-private-root-ca.cert.pem'))
, port = process.argv[2] || 8043
, hostname = process.argv[3] || 'localhost.greenlock.domains'
;
var options = {
Host: hostname
, port: port
, path: '/'
, ca: ca
};
options.agent = new https.Agent(options);
https.request(options, function(res) {
res.pipe(process.stdout);
}).end();
Et le script qui crée les fichiers de certificat:
#!/bin/bash
FQDN=$1
# make directories to work from
mkdir -p server/ client/ all/
# Create your very own Root Certificate Authority
openssl genrsa \
-out all/my-private-root-ca.privkey.pem \
2048
# Self-sign your Root Certificate Authority
# Since this is private, the details can be as bogus as you like
openssl req \
-x509 \
-new \
-nodes \
-key all/my-private-root-ca.privkey.pem \
-days 1024 \
-out all/my-private-root-ca.cert.pem \
-subj "/C=US/ST=Utah/L=Provo/O=ACME Signing Authority Inc/CN=example.com"
# Create a Device Certificate for each domain,
# such as example.com, *.example.com, awesome.example.com
# NOTE: You MUST match CN to the domain name or ip address you want to use
openssl genrsa \
-out all/privkey.pem \
2048
# Create a request from your Device, which your Root CA will sign
openssl req -new \
-key all/privkey.pem \
-out all/csr.pem \
-subj "/C=US/ST=Utah/L=Provo/O=ACME Tech Inc/CN=${FQDN}"
# Sign the request from Device with your Root CA
openssl x509 \
-req -in all/csr.pem \
-CA all/my-private-root-ca.cert.pem \
-CAkey all/my-private-root-ca.privkey.pem \
-CAcreateserial \
-out all/cert.pem \
-days 500
# Put things in their proper place
rsync -a all/{privkey,cert}.pem server/
cat all/cert.pem > server/fullchain.pem # we have no intermediates in this case
rsync -a all/my-private-root-ca.cert.pem server/
rsync -a all/my-private-root-ca.cert.pem client/
# create DER format crt for iOS Mobile Safari, etc
openssl x509 -outform der -in all/my-private-root-ca.cert.pem -out client/my-private-root-ca.crt
Par exemple:
bash make-certs.sh 'localhost.greenlock.domains'
Espérons que cela met le clou dans le cercueil sur celui-ci.
Et quelques autres explications: https://github.com/coolaj86/node-ssl-root-cas/wiki/Paneous-Self-Self-Signed-Certificates-in-node.js
Vous devez créer une copie du certificat ca racine d'un format DER avec une extension .crt:
# create DER format crt for iOS Mobile Safari, etc
openssl x509 -outform der -in all/my-private-root-ca.cert.pem -out client/my-private-root-ca.crt
Ensuite, vous pouvez simplement servir ce fichier avec votre serveur Web. Lorsque vous cliquez sur le lien, on vous demandera si vous souhaitez installer le certificat.
Pour un exemple de fonctionnement, essayez d’installer l’autorité de certification du MIT: https://ca.mit.edu/mitca.crt
Essayez d'ajouter ceci à vos options de demande.
var options = {
Host: 'localhost',
port: 8000,
path: '/api/v1/test',
// These next three lines
rejectUnauthorized: false,
requestCert: true,
agent: false
};
Cette procédure vous permet de créer à la fois une autorité de certification et un certificat:
prenez ceci ca.cnf
fichier à utiliser comme raccourci de configuration:
wget https://raw.githubusercontent.com/anders94/https-authorized-clients/master/keys/ca.cnf
créez une nouvelle autorité de certification à l'aide de cette configuration:
openssl req -new -x509 -days 9999 -config ca.cnf -keyout ca-key.pem -out ca-cert.pem
maintenant que nous avons notre autorité de certification en ca-key.pem
et ca-cert.pem
, générons une clé privée pour le serveur:
openssl genrsa -out key.pem 4096
prenez ceci server.cnf
fichier à utiliser comme raccourci de configuration:
wget https://raw.githubusercontent.com/anders94/https-authorized-clients/master/keys/server.cnf
générer la demande de signature de certificat en utilisant cette configuration:
openssl req -new -config server.cnf -key key.pem -out csr.pem
signer la demande:
openssl x509 -req -extfile server.cnf -days 999 -passin "pass:password" -in csr.pem -CA ca-cert.pem -CAkey ca-key.pem -CAcreateserial -out cert.pem
J'ai trouvé cette procédure ici , avec plus d'informations sur l'utilisation de ces certificats.
Essayez d'ajouter
agent: false,
rejectUnauthorized: false
Votre génération de clés a l'air bien. Vous ne devriez pas avoir besoin d'un ca car vous ne rejetez pas les demandes non signées.
Ajoutez .toString () à la fin de vos méthodes readFileSync afin que vous passiez une chaîne, pas un objet fichier.