使用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');


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM