客户端发起请求,服务器收到请求后将证书发送给客户端,证书中包含了服务器端的公钥,客户端收到证书后,生成一个对称密钥,并取出服务器公钥对这个对称密钥进行加密,服务端收到后用私钥进行解密,拿到客户端发送过来的对称密钥,以后客户端和服务端将采用这个对称密钥进行加密和解密数据。javascript
因此建立https服务器的时候,必需要提供服务器的私钥和证书。html
证书的生成须要经过CA(Certificate Authority,数字证书认证中心)签名,因此咱们必须先要有一个CA机构,CA机构颁发证书的时候,主要须要用到CA的私钥和CA的根证书。咱们能够经过linux自带的openssl命令进行生成,如:java
① 生成CA的私钥linux
# 生成CA机构的私钥 openssl genrsa -out ca.private.key 1024; 备注: genrsa: 表示生成RSA私有密钥,不须要生成公钥,由于公钥提取自私钥,知道了私钥就可以经过命令提取出公钥 -out: 表示生成的私钥输出文件名 1024: 表示私钥的长度为1024位,不能过小
须要注意的是,客户端在传输对称密钥的时候,须要用到服务器公钥,可是这个公钥不须要咱们本身生成,由于公钥是提取自私钥的,拿到了私钥就能够经过命令获取到对应的公钥,因此咱们后面向CA机构申请证书的时候并不须要提供服务器的公钥,只须要提供私钥便可,如:express
# 演示公钥的提取方式(仅仅演示公钥的提取过程,申请证书并不须要用到) 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的根证书
前面说过生成证书须要用到证书全部者的私钥和证书签名请求文件,如:app
# 用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这个机构了。接下来就是给服务器颁发证书了,如:ui
④ 生成服务器的私钥加密
# 生成服务器的私钥 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服务器很简单,主要就是要读取到服务器的私钥和服务器的证书,而后在建立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服务器了: