如何为HTTPS Node.js服务器使用自签名证书?
我已经开始编写API的包装器,要求所有请求都通过HTTPS。 而不是在开发和testing时向实际的API发出请求,我想在本地运行我自己的服务器来模拟响应。
我很困惑如何生成我需要创build一个HTTPS服务器和发送请求的证书。
我的服务器看起来像这样:
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);
pem文件是通过以下方式生成的:
openssl genrsa 1024 > key.pem openssl req -x509 -new -key key.pem > cert.pem
一个请求看起来像这样:
var options = { host: 'localhost', port: 8000, path: '/api/v1/test' }; https.request(options, function(res) { res.pipe(process.stdout); }).end();
有了这个设置,我得到Error: DEPTH_ZERO_SELF_SIGNED_CERT
,所以我想我需要为请求添加一个ca
选项。
所以我的问题是我应该如何产生以下内容:
- 服务器
key
? - 服务器
cert
? - 请求的
ca
?
我已经阅读了一些关于使用openssl生成自签名证书的事情,但似乎无法绕过它,并找出哪些密钥和证书在我的节点代码中使用。
更新
API提供了一个CA证书来代替默认值。 下面的代码使用他们的证书,这是我想要在本地重现。
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();
截屏
https://coolaj86.com/articles/how-to-create-a-csr-for-https-tls-ssl-rsa-pems/
完整,工作示例
- 创build证书
- 运行node.js服务器
- 在node.js客户端中没有警告或错误
- 没有警告或cURL错误
https://github.com/coolaj86/nodejs-self-signed-certificate-example
以localhost.daplie.com
为例(它指向127.0.0.1):
server.js
'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 = { key: fs.readFileSync(path.join(__dirname, 'server', 'privkey.pem')) // You don't need to specify `ca`, it's done by `ssl-root-cas` //, ca: [ fs.readFileSync(path.join(__dirname, 'server', 'my-private-root-ca.cert.pem'))] , 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.daplie.com:' + port); });
client.js
'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.daplie.com' ; 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();
和使证书文件的脚本:
make-certs.sh
#!/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
例如:
bash make-certs.sh 'localhost.daplie.com'
希望这个钉在这个棺材上。
还有一些解释: https : //github.com/coolaj86/node-ssl-root-cas/wiki/Painless-Self-Signed-Certificates-in-node.js
在iOS Mobile Safari上安装私人证书
您需要创build具有.crt扩展名的DER格式的根CA证书副本:
# 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
然后,您可以简单地与您的networking服务器提供该文件。 当你点击链接时,应该询问你是否要安装证书。
有关如何工作的示例,您可以尝试安装MIT的证书颁发机构: https : //ca.mit.edu/mitca.crt
相关的例子
- https://github.com/coolaj86/nodejs-ssl-example
- https://github.com/coolaj86/nodejs-ssl-trusted-peer-example
- https://github.com/coolaj86/node-ssl-root-cas
- https://github.com/coolaj86/nodejs-https-sni-vhost-example
- (在同一台服务器上使用SSL的多个虚拟主机)
- https://github.com/Daplie/localhost.daplie.com-certificates
- (REAL SSL证书您可以使用TODAY在本地主机上进行testing)
尝试将其添加到您的请求选项
var options = { host: 'localhost', port: 8000, path: '/api/v1/test', // These next three lines rejectUnauthorized: false, requestCert: true, agent: false };
你的关键一代看起来不错。 你不应该需要一个ca,因为你不拒绝未签名的请求。
将.toString()添加到readFileSync方法的末尾,以便实际传递一个string,而不是文件对象。
尝试添加代理:false,rejectUnauthorized:false
此过程允许您创build证书颁发机构和证书:
-
抓住这个
ca.cnf
文件作为configuration快捷键:wget https://raw.githubusercontent.com/anders94/https-authorized-clients/master/keys/ca.cnf
-
使用此configuration创build一个新的证书颁发机构:
openssl req -new -x509 -days 9999 -config ca.cnf -keyout ca-key.pem -out ca-cert.pem
-
现在我们在
ca-key.pem
和ca-cert.pem
拥有我们的authentication权限,我们来为服务器生成一个私钥:openssl genrsa -out key.pem 4096
-
抓住这个
server.cnf
文件作为configuration快捷方式:wget https://raw.githubusercontent.com/anders94/https-authorized-clients/master/keys/server.cnf
-
使用此configuration生成证书签名请求:
openssl req -new -config server.cnf -key key.pem -out csr.pem
-
签署请求:
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
我在这里find了这个过程,以及有关如何使用这些证书的更多信息。