用Node.js创建自签名的HTTPS服务器
创建自己的CA机构
- 为CA生成私钥
openssl genrsa -out c:/myca/ca-key.pem -des 1024
- 通过CA私钥生成CSR
openssl req -new -key c:/myca/ca-key.pem -out c:/myca/ca-csr.pem
- 通过CSR文件和私钥生成CA证书
openssl x509 -days 7000 -req -in c:/myca/ca-csr.pem -signkey c:/myca/ca-key.pem -out c:/myca/ca-cert.pem
注意:使用-days
指定证书有效期,默认为30天。网上找不到该参数的最大值说明。经测试最大天数为:8000
创建服务器端证书
- 为服务器生成私钥
openssl genrsa -out c:/myca/server-key.pem 1024
- 利用服务器私钥文件服务器生成CSR
这一步非常关键,你需要指定一份openssl.cnf
文件,可以从网上下载。
这里我使用的是:C:/cygwin/usr/ssl/openssl.cnf,并参照下面所需配置做了相应修改:
注:确保req_distinguished_name下没有 0.xxx 的标签,有的话把0.xxx的0. 去掉
[req]
distinguished_name = req_distinguished_name
req_extensions = v3_req
[req_distinguished_name]
countryName = Country Name (2 letter code)
countryName_default = CN
stateOrProvinceName = State or Province Name (full name)
stateOrProvinceName_default = ShangHai
localityName = Locality Name (eg, city)
localityName_default = ShangHai
organizationalUnitName = Organizational Unit Name (eg, section)
organizationalUnitName_default = src123
commonName = www.src123.com
commonName_max = 64
# 新增最后一行内容 subjectAltName = @alt_names(前2行默认存在)
[ v3_req ]
# Extensions to add to a certificate request
basicConstraints = CA:FALSE
keyUsage = nonRepudiation, digitalSignature, keyEncipherment
subjectAltName = @alt_names
# 新增 alt_names,注意括号前后的空格,DNS.x 的数量可以自己加
[alt_names]
#注意这个IP.1的设置,IP地址需要和你的服务器的监听地址一样
IP.1 = 127.0.0.1
IP.2 = 192.168.0.125
DNS.1 = www.src123.com
其他的步骤:
openssl.cnf中会要求部分文件及目录存在:
[root@localhost]#mkdir -p demoCA/{certs,crl,newcerts,private}
[root@localhost]# touch demoCA/index.txt
[root@localhost]#echo 00 > demoCA/serial
openssl req -new -key c:/myca/server-key.pem -config c:/myca/openssl.cnf -out c:/myca/server-csr.pem
- 通过服务器私钥文件和CSR文件生成服务器证书
openssl x509 -days 7000 -req -CA c:/myca/ca-cert.pem -CAkey c:/myca/ca-key.pem -CAcreateserial -in c:/myca/server-csr.pem -out c:/myca/server-cert.pem -extensions v3_req -extfile c:/myca/openssl.cnf
- 打包服务器端证书
openssl pkcs12 -export -in c:/myca/server-cert.pem -inkey c:/myca/server-key.pem -certfile c:/myca/ca-cert.pem -out c:/myca/server.pfx
创建客户端证书
- 生成客户端私钥
openssl genrsa -out c:/myca/client-key.pem
- 利用私钥生成CSR
openssl req -new -key c:/myca/client-key.pem -out c:/myca/client-csr.pem
- 生成客户端证书
openssl x509 -days 7000 -req -CA c:/myca/ca-cert.pem -CAkey c:/myca/ca-key.pem -CAcreateserial -in c:/myca/client-csr.pem -out c:/myca/client-cert.pem
- 打包客户端证书
openssl pkcs12 -export -in c:/myca/client-cert.pem -inkey c:/myca/client-key.pem -certfile c:/myca/ca-cert.pem -out c:/myca/client.pfx
HTTPS 服务器代码
var https = require('https');
var fs = require('fs');
var express = require("express");
var app = express();
var options = {
//key: fs.readFileSync('c:/myca/server-key.pem'),
//cert: fs.readFileSync('c:/myca/server-cert.pem'),
//ca: [fs.readFileSync('c:/myca/ca-cert.pem')],
pfx:fs.readFileSync('c:/myca/server.pfx'),
passphrase:'test'
};
function defaultRes(req,res){
res.writeHead(200);
res.end('hello world\n');
}
https.createServer(options,app).listen(3000,'127.0.0.1');
// routes
app.get('/', function(req, res) {
console.log("path:",req.route.path);
res.send('hello world\n');
});
app.get('/test', function(req, res) {
console.log("path:",req.route.path);
res.send('test');
});
HTTPS 客户端代码
var https = require('https');
var fs = require('fs');
var options = {
hostname:'127.0.0.1',
port:3000,
path:'/',
method:'GET',
pfx:fs.readFileSync('c:/myca/client.pfx'),
passphrase:'test',//your ca password
agent:false
};
options.agent = new https.Agent(options);
var req = https.request(options,function(res){
console.log("statusCode: ", res.statusCode);
console.log("headers: ", res.headers);
res.setEncoding('utf-8');
res.on('data',function(d){
console.log(d);
})
});
免费证书
给Node.js站点披上https外衣
SSL For Free
Installing a SSL certificate on Node.js