1. 程式人生 > >使用openssl和nodejs搭建本地https服務

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