2

一、https服务器请求处理过程

客户端发起请求,服务器收到请求后将证书发送给客户端,证书中包含了服务器端的公钥,客户端收到证书后,生成一个对称密钥并取出服务器公钥对这个对称密钥进行加密,服务端收到后用私钥进行解密,拿到客户端发送过来的对称密钥,之后客户端和服务端将采用这个对称密钥进行加密和解密数据。

所以创建https服务器的时候,必须要提供服务器的私钥和证书

二、生成服务器的私钥和证书

证书的生成需要通过CA(Certificate Authority,数字证书认证中心)签名,所以我们必须先要有一个CA机构,CA机构颁发证书的时候,主要需要用到CA的私钥和CA的根证书。我们可以通过linux自带的openssl命令进行生成,如:

① 生成CA的私钥

# 生成CA机构的私钥
openssl genrsa -out ca.private.key 1024;

备注:
genrsa: 表示生成RSA私有密钥,不需要生成公钥,因为公钥提取自私钥,知道了私钥就能够通过命令提取出公钥
-out: 表示生成的私钥输出文件名
1024: 表示私钥的长度为1024位,不能太小

需要注意的是,客户端在传输对称密钥的时候,需要用到服务器公钥,但是这个公钥不需要我们自己生成,因为公钥是提取自私钥的,拿到了私钥就可以通过命令获取到对应的公钥,所以我们后面向CA机构申请证书的时候并不需要提供服务器的公钥,只需要提供私钥即可,如:

# 演示公钥的提取方式(仅仅演示公钥的提取过程,申请证书并不需要用到)
openssl rsa -in ca.private.key -pubout -out ca.public.pem

备注:
rsa: 表示提取公钥
-in: 表示输入,即传入私钥
-pubout: 表示输出公钥

② 用CA的私钥生成CA证书签名请求CSR文件
CSR即证书签名申请(Certificate Signning Request),是生成证书时必须要用到的文件,我们要制作CA机构的根证书,必须先生成对应的CSR文件,而CSR文件必须通过私钥生成,如:

# 用CA的私钥生成CA证书签名请求csr文件
openssl req -new -key ca.private.key -out ca.csr

备注:
req: 表示生成证书签名请求
-new: 表示生成一个新的
-key: 表示生成证书签名请求时用到的私钥

生成CSR文件的时候,需要填写一些信息,比如国家城市组织或企业部门域名

③ 用CA的私钥和CA的证书签名请求文件,生成CA的根证书
前面说过生成证书需要用到证书所有者的私钥证书签名请求文件,如:

# 用CA的私钥和CA的证书签名请求文件,生成CA的根证书
openssl x509 -req -in ca.csr -signkey ca.private.key -days 3650 -out ca.root.crt

备注:
x509: 表示生成一个X509格式的证书
-req: 表示输入文件是一个"请求签发证书文件(CSR)",等待进行签发
-signkey: 表示用于签名的私钥
-days: 表示证书的有效期为10年

至此 CA的私钥和根证书已经生成完毕了,也就是说,已经拥有CA这个机构了。接下来就是给服务器颁发证书了,如:

④ 生成服务器的私钥

# 生成服务器的私钥
openssl genrsa -out server.private.key 1024

⑤ 用服务器的私钥生成服务器的证书签名请求csr文件

# 用服务器的私钥生成服务器的证书签名请求csr文件
openssl req -new -key server.private.key -out server.csr

⑥ 通过CA机构向服务器颁发证书
CA机构颁发证书需要用到CA自己的私钥CA自己的根证书以及服务器的证书签名请求文件,这些都已经生成好了,如下:

# 用CA的私钥、CA的根证书以及服务器的证书签名请求文件生成服务器的证书
openssl x509 -req -CA ca.root.crt -CAkey ca.private.key -CAcreateserial -in server.csr -out server.crt

备注:
x509: 表示生成一个X509格式的证书
-req: 表示输入文件是一个"请求签发证书文件(CSR)",等待进行签发
-CA: 表示指定CA的根证书
-CAkey: 表示指定CA的私钥
-CAcreateserial: 表示自动生成证书的序列号

所以证书其实也就是一个包含密钥的文件

三、启动https服务器

现在有了服务器证书和服务器私钥就可以创建https服务器了,创建https服务器很简单,主要就是要读取到服务器的私钥和服务器的证书,然后在创建server的时候传入即可,如:

var express = require('express');
// 引入https模块
var https = require('https');
var fs = require('fs');
//同步读取密钥和签名证书
const options = {
    key:fs.readFileSync('./server.private.key'),
    cert:fs.readFileSync('./server.crt')
}
var app = express();
// 创建https server的时候 传入服务器私钥和服务器证书
var httpsServer = https.createServer(options,app);
app.use(express.static("./dist"));
//https监听8080端口
httpsServer.listen(8080);

启动服务器后,打开浏览器访问https://localhost:8080/index.html,会提示安装证书,安装的证书如下,表示证书安装成功,可以正常访问https服务器了:
屏幕快照 2020-04-10 下午6.33.50.png


JS_Even_JS
2.6k 声望3.7k 粉丝

前端工程师