node.js express 启用 https
综述
- 服务端和客户端各有一对公钥和私钥,使用公钥加密的数据只能用私钥解密,建立https传输之前,客户端和服务端互换公钥。客户端发送数据前使用服务端公钥加密,服务端接收到数据后使用私钥解密,反之亦如此。
- 公钥私钥的生成可用openssl(linux,mac自带,windows上需要自己安装)工具来生成,具体生成步骤如下
- 1: 生成服务端客户端公钥私钥
// 生成服务器端私钥
$ openssl genrsa -out server.key 1024
//生成服务端公钥
$ openssl rsa -in server.key -pubout -out server.pem
-
如果只使用公钥/私钥,会面临一个问题,中间人攻击。在客户端与服务端呼唤公钥的过程中,中间人对服务端充当客户端,对客户端充当服务端的角色。服务端和客户端很难感受到中间人的存在。
-
为了应对这种情况,还需要对得到的服务端公钥进行认证,确定这个公钥是来自你访问的网站。证书里包含了服务器的名称,主机名,服务端的公钥,签发证书机构的名称,来自签名颁发机构的签名。在客户端拿到公钥后会对签名的公钥进行检查是否来自目标服务器,这样避免中间人攻击,生成签名证书的过程如下,
生成自签名证书
- CA (Certificate Authority,数字证书认证中心) CA的作用是为站点颁发证书,且这个证书有CA通过自己的公钥和私钥实现的签名。CA机构是专业的签发证书的机构,但是需要花钱。所以这里使用自签名证书,自己扮演CA机构,给自己颁发证书。
//生成CA私钥
$ openssl genrsa -out ca.key 1024
//生成csr文件
$ openssl req -new -key ca.key -out ca.csr
//生成自签名证书
$ openssl x509 -req -in ca.csr -signkey ca.key -out ca.crt
//生成server.csr文件
$ openssl req -new -key server.key -out server.csr
//生成带有ca签名的证书
$ openssl x509 -req -CA ca.crt -CAkey ca.key -CAcreateserial -in server.csr -out server.crt
- 最后生成服务器证书 server.crt, 注意,如果觉得生成 CA 证书,然后用 CA 签名生成的证书麻烦,也可以直接采用服务器的 key 和 csr 生成证书。
利用生成的证书,构建基于 express 框架的 https 通信模型
var express = require('express');
var https = require('https');
var http = require('http');
var fs = require('fs');
//同步读取密钥和签名证书
var options = {
key:fs.readFileSync('./keys/server.key'),
cert:fs.readFileSync('./keys/server.crt')
}
var app = express();
var httpsServer = https.createServer(options,app);
var httpServer = http.createServer(app);
app.get('/',function(req,res,next){
res.send('Hello Express+https');
});
//https监听3000端口
httpsServer.listen(3000);
//http监听3001端口
httpServer.listen(3001);
重点注意
如果你是用 request 来实现请求,https 基于自签名的证书,这时候,需要在你的程序中添加下列代码,使得你的程序可以通过 https
process.env.NODE_TLS_REJECT_UNAUTHORIZED = '0';