簡述 HTTPS 證書認證

前言

在咱們不管是對服務器仍是客戶端進行 HTTPS 進行配置時,首先須要準備好的確定是相關證書文件了,而證書文件是什麼又從哪裏能夠獲取到相關證書,而且它們又是什麼關係,最後它們怎麼在通信中起做用呢?可能不少人都不是很系統的清楚這一塊;趁如今有空整理出來給你們入門瞭解下。node

名詞解釋

  • RSA:它是一種非對稱的加密算法,裏面密鑰是一對的,分別是公鑰和私鑰;通常公鑰是由私鑰生成的;公鑰就是公開的密鑰,能夠公開給你們的,而私鑰則是須要本身保管好的不能公開的密鑰;它們互相解密,即用公鑰加密用私鑰加密,反之亦然。
  • 數字簽名:數字簽名不是用來加解密數據的,而是用來驗證數據正確性,判斷是否被篡改,場景就相似在一篇文章上籤上本身的名字供給別人驗證文章是你撰寫的;而數字簽名就是利用私鑰對原始數據的摘要(Hash 值)進行加密出來的。

Digital Signature diagram zh-CN

  • 數字證書:從名字來講就能夠看出來,數字證書和數字簽名很類似,可是不要把二者混淆,數字證書的生成是用到了數字簽名的技術而已;數字證書通常由可信的權威機構 CA 證書受權(Certificate Authority)中心頒發的。持有人將公鑰以及身份信息發送給 CA 機構進行頒發生成證書,證書文件中包括持有人公鑰、身份信息以及 CA 機構用其 CA 的私鑰對其進行的數字簽名(後面握手鍊接中會用到 CA 自身的數字證書中的公鑰對其進行校驗,這個證書叫作 CA 根證書,通常都集成在操做系統中),通常是最多見格式由X.509定義。
  • CSR:是 Certificate Signing Request 的縮寫,即證書籤名請求,這不是證書,能夠簡單理解成公鑰,生成證書時要把這個提交給權威的證書頒發機構。
  • CRT:即 certificate 的縮寫,即證書。
  • X.509:是一種證書格式,對 X.509 證書來講,認證者老是 CA 或由 CA 指定的人,一份 X.509 證書是一些標準字段的集合,這些字段包含有關用戶或設備及其相應公鑰的信息。X.509 的證書文件,通常以 .crt 爲後綴名,根據該文件的內容編碼格式,能夠分爲二種格式:PEM - Privacy Enhanced Mail,打開看文本格式以 "-----BEGIN..."、"-----END..." 開頭和結尾,內容是 Base64 編碼,文件名以 .pem、.crt、.cer 爲後綴名;Apache 和 Nginx 服務器偏向於使用這種編碼格式;DER - Distinguished Encoding Rules,打開看是二進制格式,不可讀,文件名以 .der、.crt、.cer 爲後綴名;Java 和 Windows 服務器偏向於使用這種編碼格式。從後綴名看出 CER 和 CRT 擴展幾乎是同義詞。
  • PKCS #12:我的信息交換格式(PFX,也稱爲PKCS 12)支持安全存儲證書、私鑰和證書路徑中的全部證書。PKCS 12格式是惟一可用於導出證書及其私鑰的文件格式。由 Public Key Cryptography Standards #12,PKCS#12 標準定義,以 .pfx、.p12 做爲證書文件後綴名。
  • PKCS #7:加密消息語法標準(PKCS #7),PKCS 7 格式支持證書的存儲和認證路徑中的全部證書。

正文

獲取證書

爲了獲取證書前,咱們須要生成本身的一對公鑰和私鑰。在這裏咱們會使用到一個叫作 OpenSSL 的工具庫。git

自簽名證書,無 CA 簽名

  1. 生成密鑰與證書
# 生成私鑰文件
$ openssl genrsa -out server.key 2048
# 也能夠經過指定加密算法來生成加密的文件,經過 'openssl genrsa -help' 查看支持的算法
$ openssl genrsa -aes128 -out server.key 2048

# 生成證書文件
$ openssl req -new -x509 -days 3650 \
    -subj "/C=CN/L=Guangzhou/O=Guangzhou Example Technology Co., Ltd/CN=example.com" \
    -key server.key -out server.crt

# e.g. 百度的證書中的身份信息
CN = baidu.com  # Common Name(證書所請求的域名)
O = Beijing Baidu Netcom Science Technology Co., Ltd # Organization Name
OU = service operation department   # Organization Unit Name
L = beijing     # Locality Name
S = beijing     # Sate or Province Name
C = CN          # Country Name

CA 簽名證書(非機構)

# 生成 CA 根證書
$ openssl genrsa -out ca.key 2048
$ openssl req -new -x509 -days 3650 \
    -subj "/C=CN/L=Guangzhou/O=CA Technology Co., Ltd/CN=XXX Global Root CA" \
    -key ca.key -out ca.crt

# 生成 .csr 證書籤名請求文件
$ openssl req -new \
    -subj "/C=CN/L=Guangzhou/O=Guangzhou Example Technology Co., Ltd/CN=example.com" \
    -key server.key \
    -out server.csr
# 使用 CA 根證書頒發服務器證書
$ openssl x509 -req -sha256 \
    -CA ca.crt -CAkey ca.key -CAcreateserial -days 3650 \
    -in server.csr \
    -out server.crt

它們的關係與做用

在 HTTP 協議傳輸下,數據都是以明文進行傳輸,數據安全性得不到保障;使用 HTTPS 加密通信後,數據保密和不可篡都獲得進一步的保障;根據 HTTPS 服務器不一樣的配置方式,安全性也是不盡相同,下面就是常見的 3 種方式:算法

無 CA 簽名服務器證書

這種方式須要提早將服務器的證書告知客戶端,這樣客戶端在連接服務器時才能進行對服務器證書認證。shell

通信過程(簡化)瀏覽器

client ----(tcp three way handshake)-----> server
client ----(Client Hello)-----> server
client <----(Server Hello,public key)----- server
client (經過事先保存本地的 server.crt 和服務器發過來的 server.crt 進行比較)
client ----(客戶端生成對稱密鑰,經過 server.crt 提取 public key 進行加密發送)-----> server
client ----(密鑰交換後,按照對稱密鑰進行加密通信)-----> server

在複雜的網絡環境中,服務器證書的傳輸自己也是一個很是危險的問題。若是在中間某個環節,服務器證書被監聽或替換那麼對服務器的認證也將再也不可靠。tomcat

CA 簽名服務器證書

爲了不證書的傳遞過程當中被篡改,能夠經過一個安全可靠的 CA 根證書分別對服務器和客戶端的證書進行簽名。這樣客戶端或服務器在收到對方的證書後能夠經過根證書進行驗證證書的有效性。安全

通信過程(簡化)服務器

client ----(tcp three way handshake)-----> server
client ----(Client Hello)-----> server
client <----(Server Hello,public key)----- server
client (經過 CA 根證書對服務器發過來的 server.crt 進行合法性驗證)
client ----(客戶端生成對稱密鑰,經過 public key 進行加密發送)-----> server
client ----(密鑰交換後,按照對稱密鑰進行加密通信)-----> server

雙向 CA 簽名證書

上面 2 種都是由客戶端單向驗證的,這種則是客戶端服務器雙向相互驗證。網絡

客戶端經過引入一個 CA 根證書和服務器的名字來實現對服務器進行驗證。客戶端在鏈接服務器時會首先請求服務器的證書,而後使用 CA 根證書對收到的服務器端證書進行驗證。客戶端的證書也採用 CA 根證書籤名,服務器端對客戶端進行證書認證。session

通信過程(簡化)

client ----(tcp three way handshake)-----> server
client ----(Client Hello)-----> server
client <----(Server Hello,public key)----- server
client (經過 CA 根證書對服務器發過來的 server.crt 進行合法性驗證)
client ----(客戶端生成對稱密鑰,經過 public key 進行加密發送,併發送客戶端 client.crt)-----> server
server (服務端使用 CA 根證書對 client.crt 進行作法性校驗)
client ----(密鑰交換後,按照對稱密鑰進行加密通信)-----> server

這種常見於網銀系統等交易系統的網站或者 API 使用,確保客戶端攜帶證書進行訪問;當無證書的客戶端沒法進行訪問,當訪問時會出現 400 Bad Reques <No required SSL certificate was sent >

瀏覽器證書導入須要裝換爲 PKCS #12 證書文件才能導入,命令以下:

openssl pkcs12 -export -inkey client.key -in client.crt -out client.pfx
# 輸入口令,導入證書後再請求則會彈出選擇證書的選項就正常訪問了

Nginx 配置 etc.

從 JKS 文件中提取服務證書

說明:JKS 文件擴展名是 .jks 或 .keystore

  1. 查看jks文件中的entry
keytool -list -keystore server.jks
  1. 將」.jks」轉爲」.p12」(PKCS12格式的證書庫)
keytool -importkeystore -srckeystore server.jks -srcalias tomcat -destkeystore server.p12 -deststoretype PKCS12
  1. 獲得配置服務器使用的 server.crtserver.keyca.crt 文件
openssl pkcs12 -in server.p12 -nodes -nocerts -out server.key
openssl pkcs12 -in server.p12 -nodes -nokeys -clcerts -out server.crt
openssl pkcs12 -in server.p12 -nodes -nokeys -cacerts -out ca.crt

使用加密的私鑰配置 Nginx 支持 SSL 時,並使用下面命令去除私鑰必須的口令(不然 start、reload 都得輸入密碼)

$ cp server.key server.key.org
$ openssl rsa -in server.key.org -out server.key

Nginx 配置

server {
    listen       443 ssl;
    server_name  localhost;

    ssl                  on;
    ssl_certificate      ../cert/server.crt;
    ssl_certificate_key  ../cert/server.key;
    
    ssl_client_certificate ../cert/ca.crt;
    ssl_verify_client on;

    ssl_session_timeout  5m;

    ssl_protocols  TLSv1 TLSv1.1 TLSv1.2;
    ssl_ciphers  ECDHE-RSA-AES256-SHA384:AES256-SHA256:RC4:HIGH:!MD5:!aNULL:!eNULL:!NULL:!DH:!EDH:!AESGCM;
    ssl_prefer_server_ciphers on;
    ssl_session_cache shared:SSL:10m;

    location / {
     proxy_redirect off;
     proxy_set_header Host $host;
     proxy_set_header X-Real-IP $remote_addr;
     proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
     proxy_pass http://localhost:8080;
    }
}

參考

相關文章
相關標籤/搜索