使用openssl和nodejs搭建本地https服务

  本地开发有时会遇到必须使用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');

猜你喜欢

转载自www.cnblogs.com/zzmiaow/p/10201035.html