https雙向認證 本地創建自定義證書 nginx配置https雙向認證

前言

本篇博文將爲你解答這些問題:

  1. https單相認證和雙向認證的講解
  2. https證書獲取途徑:騰訊雲、阿里雲、自簽名證書
  3. nginx如何配置https雙向認證?
  4. 如何驗證https雙向認證?
  5. uni-app 配置 https 自簽名客戶端證書
  6. mac如何安裝客戶端證書
  7. chrome瀏覽器訪問自簽名證書地址顯示【您的連接不是私密連接】解決辦法

如果有什麼不懂,可以留言溝通

正文

1. https單相認證和雙向認證的講解

單向認證流程

  1. 客戶端發起建立HTTPS連接請求,將SSL協議版本的信息發送給服務器端;
  2. 服務器端將本機的公鑰證書(server.crt)發送給客戶端;
  3. 客戶端讀取公鑰證書(server.crt),取出了服務端公鑰;
  4. 客戶端生成一個隨機數(密鑰R),用剛纔得到的服務器公鑰去加密這個隨機數形成密文,發送給服務端;
  5. 服務端用自己的私鑰(server.key)去解密這個密文,得到了密鑰R
  6. 服務端和客戶端在後續通訊過程中就使用這個密鑰R進行通信了。

雙向認證流程

  1. 客戶端發起建立HTTPS連接請求,將SSL協議版本的信息發送給服務端;
  2. 服務器端將本機的公鑰證書(server.crt)發送給客戶端;
  3. 客戶端讀取公鑰證書(server.crt),取出了服務端公鑰;
  4. 客戶端將客戶端公鑰證書(client.crt)發送給服務器端;
  5. 服務器端使用根證書(root.crt)解密客戶端公鑰證書,拿到客戶端公鑰;
  6. 客戶端發送自己支持的加密方案給服務器端;
  7. 服務器端根據自己和客戶端的能力,選擇一個雙方都能接受的加密方案,使用客戶端的公鑰加密8. 後發送給客戶端;
  8. 客戶端使用自己的私鑰解密加密方案,生成一個隨機數R,使用服務器公鑰加密後傳給服務器端;
  9. 服務端用自己的私鑰去解密這個密文,得到了密鑰R
  10. 服務端和客戶端在後續通訊過程中就使用這個密鑰R進行通信了。

整個雙向認證的流程需要六個證書文件:

  1. 服務器端公鑰證書:server.crt
  2. 服務器端私鑰文件:server.key
  3. 根證書:root.crt
  4. 客戶端公鑰證書:client.crt
  5. 客戶端私鑰文件:client.key
  6. 客戶端集成證書(包括公鑰和私鑰,用於瀏覽器訪問場景):client.p12

2. https證書獲取途徑:騰訊雲、阿里雲、自簽名證書

如果你只需要單向認證,在騰訊雲的 【SSL證書】這個產品下,即可申請到免費的單域名證書。也可以再阿里雲平臺的【SSL 證書(應用安全)】這個產品下申請免費的單域名證書。

如果你需要雙向認證,有兩種辦法:

  1. 購買正規廠商出售的證書,不過價格相對比較高昂。
  2. 使用自簽名證書,自己在本地用開源工具 openssl 生成所需要的6個證書文件

使用 openssl 工具生成證書文件

openssl安裝請自行搜索

  1. 生成自簽名根證書

    1. 創建根證書
    openssl genrsa -out root.key 1024
    
    1. 創建根證書請求文件
    openssl req -new -out root.csr -key root.key
    

    這裏有許多參數需要填寫,請自行填寫:A challenge password 密碼可以不設置

    Country Name (2 letter code) [XX]:cn
    State or Province Name (full name) []:bj
    Locality Name (eg, city) [Default City]:bj
    Organization Name (eg, company) [Default Company Ltd]:shuiche
    Organizational Unit Name (eg, section) []:test
    Common Name (eg, your name or your servers hostname) []:root
    Email Address []:a.alibaba.com
    A challenge password []:
    An optional company name []:
    
    1. 創建根證書
    openssl x509 -req -in root.csr -out root.crt -signkey root.key -CAcreateserial -days 3650
    
  2. 生成服務端證書

    1. 生成服務器端證書私鑰
    openssl genrsa -out server.key 1024
    
    1. 生成服務器證書請求文件
    openssl req -new -out server.csr -key server.key
    

    這裏有許多參數需要填寫

    Country Name (2 letter code) [XX]:cn
    State or Province Name (full name) []:bj
    Locality Name (eg, city) [Default City]:bj
    Organization Name (eg, company) [Default Company Ltd]:shuiche
    Organizational Unit Name (eg, section) []:test
    Common Name (eg, your name or your servers hostname) []:root
    Email Address []:a.alibaba.com
    A challenge password []:
    An optional company name []:
    
    1. 生成服務器端公鑰證書
    openssl x509 -req -in server.csr -out server.crt -signkey server.key -CA root.crt -CAkey root.key -CAcreateserial -days 3650
    

有些教程裏生成的是 .pem 格式的公鑰證書,.pem 和 .crt 其實是一樣的。都代表公鑰證書

經過上面的三個命令,我們得到:

server.key:服務器端的密鑰文件
server.crt:有效期十年的服務器端公鑰證書,使用根證書和服務器端私鑰文件一起生成

  1. 生成客戶端證書

    1. 生成客戶端證書密鑰:
    openssl genrsa -out client.key 1024
    
    1. 生成服務器證書請求文件
    openssl req -new -out client.csr -key client.key
    

    這裏有許多參數需要填寫

    Country Name (2 letter code) [XX]:cn
    State or Province Name (full name) []:bj
    Locality Name (eg, city) [Default City]:bj
    Organization Name (eg, company) [Default Company Ltd]:shuiche
    Organizational Unit Name (eg, section) []:test
    Common Name (eg, your name or your servers hostname) []:root
    Email Address []:a.alibaba.com
    A challenge password []:
    An optional company name []:
    
    1. 生客戶端證書
    openssl x509 -req -in client.csr -out client.crt -signkey client.key -CA root.crt -CAkey root.key -CAcreateserial -days 3650
    
    1. 生客戶端p12格式證書,需要輸入一個密碼,選一個好記的,比如123456

    密碼一定要記牢,安裝客戶端證書時需要填寫的

    openssl x509 -req -in client.csr -out client.crt -signkey client.key -CA root.crt -CAkey root.key -CAcreateserial -days 3650
    

經過上面的四個命令,我們得到:

client.key:客戶端的私鑰文件
client.crt:有效期十年的客戶端證書
client.p12: 證書文件包含客戶端的公鑰和私鑰,主要用來給瀏覽器訪問使用(uniapp再配置雙向認證時也需要)

3. nginx如何配置雙向認證

直接上配置文件:

server {
   listen       443 ssl; # 開啓ssl
   server_name  www.******.com; # 域名或者本機ip 【自行修改成你的值】
   ssl_certificate      /usr/local/webserver/nginx/conf/cert/server.crt; # 服務端證書
   ssl_certificate_key  /usr/local/webserver/nginx/conf/cert/server.key; # 服務端私鑰

   ssl_session_cache    shared:SSL:1m; # 配置共享會話緩存大小
   ssl_session_timeout  5m; # session有效期5分鐘
   ssl_protocols  SSLv2 SSLv3 TLSv1 TLSv1.1 TLSv1.2; #啓用指定的協議
   ssl_ciphers  ALL:!DH:!EXPORT:!RC4:+HIGH:+MEDIUM:-LOW:!aNULL:!eNULL; #加密算法
   ssl_prefer_server_ciphers  on; # 優先採取服務器算法
   ssl_verify_client on;# 開啓客戶端證書校驗
   ssl_client_certificate  /usr/local/webserver/nginx/conf/cert/ca.crt; # CA證書用於驗證客戶端證書的合法性
   ssl_verify_depth 6; # 校驗深度
   ssl_trusted_certificate /usr/local/webserver/nginx/conf/cert/ca.crt; # 將CA證書設爲受信任的證書
   # 減少點擊劫持
   add_header  X-Frame-Options DENY;
   # 禁止服務器自動解析資源類型
   add_header  X-Content-Type-Options  nosniff;
   # 防止XSS攻擊
   add_header  X-Xss-Protection 1;

   location / {
     # start  防止跨域問題
     add_header Access-Control-Allow-Origin *;
     add_header Access-Control-Allow-Methods 'GET, POST, OPTIONS';
     add_header Access-Control-Allow-Headers 'DNT,X-Mx-ReqToken,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Authorization';
     
     if ($request_method = 'OPTIONS') {
         return 204;
     }
     # end
     root   /home/ljcw/micro/;
     index  index.html index.htm;
   	  try_files $uri $uri/ /index.html;
   }
}

4. 如何驗證https雙向認證?

  1. 攜帶客服端證書訪問:
#--cert 指定客戶端公鑰證書的路徑
#--key 指定客戶端私鑰文件的路徑
#-k 使用本參數不校驗證書的合法性,因爲我們用的是自簽名證書
#-v 可以使用 -v 來觀察具體的SSL握手過程
curl --cert ./client2.crt --key ./client2.key https://integration-fred2.fredhuang.com -k -v
  1. 不攜帶客戶端證書訪問
curl https://integration-fred2.fredhuang.com -k

5. uni-app 配置 https 自簽名客戶端證書

  1. 調用 uni.configMTLS 函數。查看文檔 https://uniapp.dcloud.net.cn/api/request/request.html#configmtls

uni.configMTLS 直接在 App.vue 的 onLaunch 中調用一次即可

  1. 正常使用 uni.request 就可以了
uni.configMTLS({
      certificates: [{
      host: 'www.test.com',  // 換成你證書設定的域名(也就是https請求的域名)
      client: '/static/client.p12',
      clientPassword: '123456',
      server: ['/static/server.pem']
  }],
  complete (res) {
      console.log('res', res)
  }
})

如果報錯這個 "errMsg": "request:fail abort statusCode:-1 Hostname www.unihttps.com not verified:\n certificate: sha256/4cIBWyy+2BlD/ME12B4hIRVEefrl5X0nL0/3DGISfKA=\n DN: CN=www.unihttps.com\n subjectAltNames: []"

問題所在:server證書沒有配置-SAN參數,參考這個 使用openssl生成SAN證書

6. mac如何安裝客戶端證書

直接雙擊 client.p12 文件,按提示操作
既可以在:mac的【鑰匙串訪問】這個app裏面找到,然後在證書文件右鍵,選擇永久信任證書即可

7. chrome瀏覽器訪問自簽名證書地址顯示【您的連接不是私密連接】解決辦法

解決辦法:

在當前頁面用鍵盤輸入 thisisunsafe ,不是在地址欄輸入,就直接敲鍵盤就行了,頁面即會自動刷新進入網頁。

後記

參考文章:
Chrome 您的連接不是私密連接解決辦法https://zhuanlan.zhihu.com/p/341857389
SSL 雙向認證的一個小問題https://maoxian.de/2016/02/1370.html
阿里雲 HTTPS雙向認證(Mutual TLS authentication)(https://help.aliyun.com/document_detail/160093.html
SSL 客戶端驗證https://graycarl.me/2016/09/27/ssl-client-side-authentication.html
nginx配置https雙向認證https://juejin.cn/post/6909621056848265230
uni.request接口https://uniapp.dcloud.net.cn/api/request/request.html#configmtls
關於uniapp雙向認證https的經驗分享 https://ask.dcloud.net.cn/article/39567

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章