最近工作上需要建立程式之間的 TLS 連線,而 TLS 之間的連線步驟需要驗證憑證 (Certificate) ,讓之間的加密連線可以成立。不過由於處於測試階段,需要自己產生憑證出來。因此學習使用 Openssl 來產生憑證,也藉此讓自已對 TLS 連線和憑證機制有更清楚的了解。
TLS 介紹
傳輸層安全協議(Transport Layer Security,縮寫:TLS),前身為安全通訊協定(Secure Sockets Layer,縮寫:SSL),由網景公司 (Netscape) 開發出來用在 http 協定上,後來由 IETF 將 SSL 進行標準化,就是後來的 TLS 。
TLS 在建立連線時,會經過以下的步驟:
- client 送出 ClientHello 訊息給 server ,裡面包含可支援的 TLS protocol,一個由 client 端隨機產生的數字(隨機數字只用在此次連線期間,避免被封包重播攻擊),以及支援的加密和壓縮演算法。
- server 回應 ServerHello 訊息,提供要使用的 TLS protocol ,一個由 server 端隨機產生的數字,以及要使用的加密和壓縮演算法。
- server 根據上面選擇的 TLS protocol 和加密及壓縮演算法,提供憑證給 client
- client 驗證 server 提供的憑證,將憑證內的 public key 取出
- 利用 server 提供的 public key ,將 client 的憑證,沒有憑證則隨機產生的 public key ,加密送回。
- 雙方使用交換出來的資訊,產生一組通訊用的加解密方式,有對稱式或非對稱式,取決於採用哪種演算法。
- 連線建立。
使用 Openssl 產生憑證
以下描述使用 openssl 來產生可供 TLS 連線所需的憑證,主要參考 OpenSSL Certificate Authority 這個網站的步驟來一步一步執行,根據自己的需求修改設定。
建立 root 憑證
一般公開網路上憑證不會是自己產生的,因為網路傳輸過程中不能確保會不會被偽造或修改。因此為了有可靠的信任機制,於是就有了憑證機構 (Certificate Authority, CA) ,由憑證機構產生憑證。最上層憑證機構通常由被信任的第三方公正機關來擔任,然後對個人或公司團體產生憑證簽章,如此才能確保憑證可以不被修改。
以瀏覽器為例,存有一串信任的憑證機構,藉由檢視連線網站的憑證是否由這些憑證機構產生,來判別網站可否受信任,不信任情況下就會出現不安全連線的提示。
而對公司企業內的私人網路來說, 不需要透過第三方憑證機構,因此會由自己產生 root 憑證,往下建立一連串的認證階層。也因此 root 憑證必須保護好,放置在與網路隔絕的環境並只有特定人士可以存取。一般網路上的認證機構的 root 憑證會互相簽章,表示彼此信任,而自己產生的 root 憑證因沒有其他機關互相簽章,因此會是自我簽章的憑證。
步驟:
產生 root key。
1234mkdir /root/cacd /root/caopenssl genrsa -aes256 -out private/ca.key.pem 4096chmod 400 private/ca.key.pem參照 config 產生 openssl.cnf
產生自我簽章的 root 憑證。
123456openssl req -config openssl.cnf \-key private/ca.key.pem \-new -x509 -days 7300 -sha256 -extensions v3_ca \-subj "/C=TW/ST=Taipei/O=RAIX/OU=RAIX.IO/CN=raix.io.rootca/emailAddress=raix@mail.com" \-out certs/ca.cert.pemchmod 444 certs/ca.cert.pemroot 憑證過期日期建議設定長一點,因為是最重要的環節,不太適合頻繁的過期造成整串憑證失效。
另外因為是產生自我簽章的憑證,和接下來產生 intermediate 或 client/server 的 Certificate signing request (CSR) 指令多了
-x509
參數。驗證 root 憑證
1openssl x509 -noout -text -in certs/ca.cert.pem
建立 intermediate 憑證
intermediate 憑證介於 root 和 client server 之間,可避免 root 憑證直接被使用,也可用來分群組,區分可使用的範圍。
步驟
設置相關資料夾和資訊
1234567mkdir /root/ca/intermediatecd /root/ca/intermediatemkdir certs crl csr newcerts privatechmod 744 privatetouch index.txtecho 1000 > serialecho 1000 > crlnumber產生 intermediate key
123openssl genrsa -aes256 \-out private/intermediate.key.pem 4096chmod 400 private/intermediate.key.pem修改 openssl.cnf 產生 openssl-im.cnf
123456[ CA_default ]dir = /root/ca/intermediateprivate_key = $dir/private/intermediate.key.pemcertificate = $dir/certs/intermediate.cert.pemcrl = $dir/crl/intermediate.crl.pempolicy = policy_loose產生 intermediate CSR
1234openssl req -config openssl-im.cnf -new -sha256 \-subj "/C=TW/ST=Taipei/O=RAIX/OU=RAIX.IO/CN=raix.io.imca/emailAddress=raix@mail.com"\-key private/intermediate.key.pem \-out csr/intermediate.csr.pemCertificate signing request (CSR) 裡紀錄個人或組織的資訊,並且提供給憑證機構簽章。
對 intermediate CSR 簽上 root 憑證,產生 intermediate 憑證
12345openssl ca -config /root/ca/openssl.cnf -extensions v3_intermediate_ca \-days 3650 -notext -md sha256 \-in csr/intermediate.csr.pem \-out certs/intermediate.cert.pemchmod 444 certs/intermediate.cert.pem驗證 intermediate 憑證
1234openssl x509 -noout -text \-in intermediate/certs/intermediate.cert.pemopenssl verify -CAfile certs/ca.cert.pem \intermediate/certs/intermediate.cert.pem產生憑證鍊 (certificate chain)
123cat intermediate/certs/intermediate.cert.pem \certs/ca.cert.pem > intermediate/certs/ca-chain.cert.pemchmod 444 intermediate/certs/ca-chain.cert.pem當應用程式要驗證 intermediate 憑證時,也需要同時驗證 root 憑證,因此需要產生憑證鍊來完成一整串驗證。
建立 client/server 憑證
最後就是對要使用的 client/server 產生憑證,讓彼此之間 TLS 連線可以成立,確保處於安全的連線下。
步驟
產生 client/server key
123cd /root/ca/intermediate/openssl genrsa -out private/client.raix.io.key.pem 2048chmod 444 private/client.raix.io.key.pem產生 client/server CSR
1234openssl req -config openssl-im.cnf \-key intermediate/private/client.raix.io.key.pem \-subj "/C=TW/ST=Taipei/O=RAIX/OU=RAIX.IO/CN=client.raix.io/emailAddress=raix@mail.com" \-new -sha256 -out client.raix.io.csr.pem產生 client/server 憑證
12345openssl ca -config openssl-im.cnf \-extensions server_cert -days 375 -notext -md sha256 \-in intermediate/csr/client.raix.io.csr.pem \-out intermediate/certs/client.raix.io.cert.pemchmod 444 certs/client.raix.io.cert.pem驗證憑證
1234openssl x509 -noout -text \-in certs/client.raix.io.cert.pemopenssl verify -CAfile intermediate/certs/ca-chain.cert.pem \certs/client.raix.io.cert.pem
參考資料
Wiki: Transport Layer Security
Wiki: Certificate authority
Wiki: Certificate signing request
OpenSSL Certificate Authority