1. 程式人生 > 實用技巧 >node https 雙向認證

node https 雙向認證

本部落格結合一下連線

https://www.cnblogs.com/wzs5800/p/12778904.html.

https://www.cnblogs.com/wzs5800/p/12779223.html

https://www.cnblogs.com/mhc-fly/p/8472972.html

一、生成證書

使用cfssl工具: 工具下載地址

CA證書

1.準備ca-config.json(根證書配置檔案)

{
    "signing": {
        "default": {
            "expiry": "43800h"
        },
        "profiles": {
            "server": {
                "expiry": "43800h",
                "usages": [
                    "signing",
                    "key encipherment",
                    "server auth"
                ]
            },
            "client": {
                "expiry": "43800h",
                "usages": [
                    "signing",
                    "key encipherment",
                    "client auth"
                ]
            },
            "peer": {
                "expiry": "43800h",
                "usages": [
                    "signing",
                    "key encipherment",
                    "server auth",
                    "client auth"
                ]
            }
        }
    }
}

ca-csr.json(根證書請求配置檔案)

注意

因為自簽證書,ca-csr配置裡的CN不要以"www"開頭,測試過www開頭會導致通訊失敗。

{
    "CN": "MYCA",
    "key": {
        "algo": "rsa",
        "size": 2048
    },
    "names": [
        { 
            "C": "CN",
           "ST": "Guangzhou",
           "L": "Guangzhou",
           "O": "組織",
           "OU": "部門"
       }    
    ]
}

生成CA證書

cfssl.exe gencert -initca ca-csr.json | cfssljson.exe -bare ca -

服務端證書

server-csr.json

hosts為服務端的IP,請根據需要自行補充。

{
    "CN": "my-server",
    "hosts": [
      "127.0.0.1"
    ],
    "key": {
        "algo": "rsa",
        "size": 2048
    },
    "names": [
        {
           "C": "CN",
           "ST": "Guangzhou",
           "L": "Guangzhou",
           "O": "組織",
           "OU": "部門"
        }
    ]
}

生成服務端證書

cfssl.exe gencert -ca=ca.pem\
-ca-key=ca-key.pem\
-config=ca-config.json\
-profile=server server-csr.json | cfssljson.exe -bare server

客戶端證書

客戶端證書和服務端證書生成步驟一樣,只不過不需要配置host欄位。

client-csr.json

{
    "CN": "my-client",
    "key": {
        "algo": "rsa",
        "size": 2048
    },
    "names": [
        {
           "C": "CN",
           "ST": "Guangzhou",
           "L": "Guangzhou",
           "O": "組織",
           "OU": "部門"
        }
    ]
}

生成客戶端證書

cfssl.exe gencert -ca=ca.pem\
-ca-key=ca-key.pem\
-config=ca-config.json\
-profile=client client-csr.json | cfssljson.exe -bare client

最後會生成以下證書目錄如下

├── ca.csr
├── ca.pem
├── ca-key.pem
├── client.csr
├── client.pem
├── client-key.pem
├── server.csr
├── server.pem
├── server-key.pem
openssl x509 -req -in ca.csr -signkey ca.key -out ca.crt //生成ca.crt

openssl x509 -req -CA ca.crt -CAkey ca.key -CAcreateserial -in server.csr -out server.crt //生成server.crt

openssl x509 -req -CA ca.crt -CAkey ca.key -CAcreateserial -in client.csr -out client.crt //生成client.crt

二、Node程式碼

  服務端

const https = require('https');
const fs = require('fs');

const options = {
  key: fs.readFileSync('./certificate/server-key.pem'),
  cert: fs.readFileSync('./certificate/server.pem'),
  ca: [fs.readFileSync('./certificate/ca.pem')],
  // 使用客戶端證書驗證
  requestCert: true,
  // 如果沒有請求到客戶端來自信任CA頒發的證書,拒絕客戶端的連線
  rejectUnauthorized: true
};
const port = 8081;
https.createServer(options, (req, res) => {
  console.log('server connected', res.connection.authorized ? 'authorized' : 'unauthorized');
  res.writeHead(200);
  res.end('hello world!\n');
}).listen(port, () => {
  console.log(`running server https://127.0.0.1:${port}`)
});

  客戶端

const https = require('https');
const fs = require('fs');

const options = {
  hostname: '127.0.0.1',
  port: 8081,
  path: '/',
  method: 'GET',
  key: fs.readFileSync('./certificate/client-key.pem'),
  cert: fs.readFileSync('./certificate/client.pem'),
  ca: [fs.readFileSync('./certificate/ca.pem')],
  agent: false,
  // 開啟雙向認證
  rejectUnauthorized: true
};

// options.agent = new https.Agent(options);
const req = https.request(options, (res) => {
  console.log('client connected', res.connection.authorized ? 'authorized' : 'unauthorized');
  console.log('狀態碼:', res.statusCode);
  res.setEncoding('utf-8');
  res.on('data', (d) => {
    process.stdout.write(d);
  });
});

req.on('error', (e) => {
  console.error(e);
});

req.end();

三、火狐瀏覽器證書生成

首先 不能在火狐裡對要訪問的網址新增例外

開啟 選項->高階->檢視證書->證書機構->匯入。先擇服務端ca.crt後根據提示匯入證書

生成p12檔案

openssl pkcs12 -export -clcerts -in client.crt -inkey client-key。pem -out client.p12

密碼隨便輸入

火狐瀏覽器 開啟 選項->高階->檢視證書->您的證書->匯入 p12 檔案, 輸入上邊設定的密碼