本地开发有时会遇到必须使用https服务的情况,这里介绍一下使用openssl自签名证书,并使用nodejs开启https服务。
1. 安装openssl
在http://slproweb.com/products/Win32OpenSSL.html可以找到openssl安装包,可以根据介绍下载对应版本安装,安装完成后将安装位置bin目录的文件路径添加到系统环境变量,此时就可以在全局使用openssl指令,打开命令行输入`openssl -version`查看openssl是否正确安装。安装完成后,选择一个存放证书的位置,打开控制台通过openssl生成证书。
生成证书的步骤主要包含创建本地CA机构、创建服务器证书和创建客户端证书。
2.生成证书
在创建证书的过程中,会要求输入密码和证书信息(浏览器地址左侧有一个锁,点开后选择证书看到的信息),密码在输入过程中,控制台不会有任何显示。输入信息需要填写国家(ZH)、省市、机构等信息,由于自己签名并没有公网的可认证性,所以这些信息随便填都可以。后面会要求输入密码生成证书,所以需要记住密码。
CA:
生成私钥:
openssl genrsa -out ca-key.pem -des 1024
生成公钥:
openssl req -new -key ca-key.pem -out ca-csr.pem
生成证书:
openssl x509 -req -in ca-csr.pem -signkey ca-key.pem -out ca-cert.pem
查看文件夹中应该会有 ca-key.pem 、 ca-csr.pem、 ca-cert.pem三个文件,如果其中有步骤出现操作,将这一段指令重新输入即可覆盖原文件。
服务端:
服务端生成公钥需要读取配置文件,创建openssl.cnf文件在统计目录下,内容为:
[req] ???????????distinguished_name = req_distinguished_name ???????????req_extensions = v3_req ???????????????????[req_distinguished_name] ???????????countryName = ZH ???????????countryName_default = CN ???????????stateOrProvinceName = BeiJing ??????????stateOrProvinceName_default = BeiJing ???????????localityName = ChengDu ???????????localityName_default = YaYunCun ???????????organizationalUnitName ?= public section ???????????organizationalUnitName_default ?= Domain Control Validated ???????????commonName = Internet Widgits Ltd ???????????commonName_max ?= 64 ???????????????????[ v3_req ] ???????????# Extensions to add to a certificate request ???????????basicConstraints = CA:FALSE ???????????keyUsage = nonRepudiation, digitalSignature, keyEncipherment ???????????subjectAltName = @alt_names ???????????????????[alt_names] ???????????IP.1 = 127.0.0.1
上述信息也是证书相关的信息,后面的值都是随意写的,替换与否都没有关系。
生成私钥:
openssl genrsa -out server-key.pem 1024
生成公钥:
openssl req -new -key server-key.pem -config openssl.cnf -out server-csr.pem
生成证书:
openssl x509 -req -CA ca-cert.pem -CAkey ca-key.pem -CAcreateserial -in server-csr.pem -out server-cert.pem -extensions v3_req -extfile openssl.cnf
客户端:
搭建https服务器不需要客户端证书,生成指令和上面类似:
生成私钥:
openssl genrsa -out client-key.pem
生成公钥:
openssl req -new -key client-key.pem -out client-csr.pem
生成证书:
openssl x509 -req -CA ca-cert.pem -CAkey ca-key.pem -CAcreateserial -in client-csr.pem -out client-cert.pem
3. 使用nodejs搭建https服务
关键部分是https.createServer传递的options参数:
let options = { ?key: fs.readFileSync(‘./server-key.pem‘), ?ca: [fs.readFileSync(‘./ca-cert.pem‘)], ?cert: fs.readFileSync(‘./server-cert.pem‘)};
使用https模块和fs模块,搭建服务器访问本地html文件:
const https = require(‘https‘);const fs = require(‘fs‘);const url = require(‘url‘)// 引入证书let options = { ?key: fs.readFileSync(‘./server-key.pem‘), ?ca: [fs.readFileSync(‘./ca-cert.pem‘)], ?cert: fs.readFileSync(‘./server-cert.pem‘)};// 创建https服务https.createServer(options,function(req,res){ ?// 获取请求文件路径 ?var pathname = url.parse(req.url).pathname; ?// 设置默认访问index.html文件 ?if(pathname == ‘/‘) { ???pathname = ‘/index.html‘; ?} ?// 读取文件,并设置为html类型,返回给浏览器 ?fs.readFile(__dirname + pathname, function (err, data) { ???if (err) { ?????if(pathname == ‘/favicon.ico‘) { ???????res.writeHead(200, {‘Content-Type‘: ‘text/html; charset=utf-8;‘}); ???????res.end(); ?????} ?????console.error(err); ?????res.writeHead(404, {‘Content-Type‘: ‘text/html‘}); ???} else { ?????res.writeHead(200, {‘Content-Type‘: ‘text/html; charset=utf-8;‘}); ?????res.write(data.toString()); ???} ???res.end(); ?});// 监听本地3000端口}).listen(3000,‘127.0.0.1‘);
当然,使用框架也可以更改为https服务,例如express或者koa2.
例如koa2,在bin目录www文件中替换以下为代码:
const https = require(‘https‘); ???const fs = require(‘fs‘); ???let options = { ?????key: fs.readFileSync(‘./keys/server-key.pem‘), ?????ca: [fs.readFileSync(‘./keys/ca-cert.pem‘)], ?????cert: fs.readFileSync(‘./keys/server-cert.pem‘) ???}; ???// 将原本开启服务的代码注释更换为以下部分,根据需求监听端口 ???https.createServer(options,function(req,res){ ?????res.writeHead(200); ?????res.end(app.callback()); ???}).listen(3000,‘127.0.0.1‘);
使用openssl和nodejs搭建本地https服务
原文地址:https://www.cnblogs.com/zzmiaow/p/10201035.html