前言
最近項目裏面用到了SSL雙向認證和傳輸加密的技術,研究了一下,想把相關的指令和代碼分享出來,以期後來者能夠少踩坑,順利解決問題。我們的項目服務器是C,客戶端爲Java,CS架構,中間通過Socket通訊。
OpenSSL和Java KeyStore本質上沒有關係,只是客戶端用到Java,Java裏面SSL認證加密的密碼和證書需要存儲到KeyStore這個容器裏面,所以OpenSSL產生的相關資料需要導入keyStore容器。當然也可以反過來,用Java的KeyTool產生資料,再導出密碼、證書,給服務器端C使用。不過OpenSSL比Java的keytool強大很多,故選擇前一種方式。OpenSSL產生資料,存入KeyStore。本文只介紹用到的一系列指令。
這裏涉及到三份證書。根證書(root.crt),自簽名的,用於給其它證書授權。服務器證書(server.crt)。以及客戶端證書(client.crt),一般系統不需要,我們的系統是雙向認證,客戶端也要證書。
指令列表
- openssl genrsa -out rootkey.pem 2048
生成根證書的密匙。 - openssl req -x509 -new -key rootkey.pem -out root.crt
生成根證書。注意-x509,與步驟4和7不同。需要輸入機構相關信息。 - openssl genrsa -out clientkey.pem 2048
生成客戶端的密匙。 - openssl req -new -key clientkey.pem -out client.csr 生成客戶端證書的請求文件。請求根證書來簽發。
- openssl x509 -req -in client.csr -CA root.crt -CAkey rootkey.pem -CAcreateserial -days 3650-out client.crt
用根證書來簽發客戶端請求文件,生成客戶端證書client.crt。 - openssl genrsa -out serverkey.pem 2048
生成服務器端的密匙。 - openssl req -new -key serverkey.pem -out server.csr
生成服務器端證書的請求文件。請求根證書來簽發。 - openssl x509 -req -in server.csr -CA root.crt -CAkey rootkey.pem -CAcreateserial -days 3650-out server.crt
用根證書來簽發服務器端請求文件,生成服務器端證書server.crt。 - openssl pkcs12 -export -in client.crt -inkey clientkey.pem -out client.pkcs12
打包客戶端資料爲pkcs12格式(client.pkcs12)。需要輸入密碼,請記住。 - openssl pkcs12 -export -in server.crt -inkey serverkey.pem -out server.pkcs12
打包服務器端資料爲pkcs12格式(server.pkcs12 )。需要輸入密碼,請記住。 - keytool -importkeystore -srckeystore client.pkcs12 -destkeystore client.jks -srcstoretype pkcs12
生成客戶端keystore(client.jks)。使用keytool的importkeystore指令。pkcs12轉jks。需要pkcs12密碼和jks密碼。 - keytool -importkeystore -srckeystore server.pkcs12 -destkeystore server.jks -srcstoretype pkcs12
生成服務器端keystore(server.jks)。使用keytool的importkeystore指令。pkcs12轉jks。需要pkcs12密碼和jks密碼。 - keytool -importcert -keystore server.jks -file root.crt
這一步不一定需要的。我發現服務器使用JDK6和JDK7的時候,必須要把根證書加到服務器證書裏面,否則交談失敗。nul certification。Google裏面很多結果,但是都不靈光。
後記
理解概念是最重要的,路有很多條。以上指令還缺少幾條,用來生成服務器端的trustkeystore,客戶端的trustkeystore。trustkeystore裏面不包含私匙。
參考鏈接
補上TrustKeyStore指令
- keytool -importcert -alias ca -file root.crt -keystore clienttrust.jks
生成Client端的對外KeyStore。先把根證書放到裏面。 - keytool -importcert -alias clientcert -file client.crt -keystore clienttrust.jks
把Client證書加到對外KeyStore裏面。 - keytool -importcert -alias ca -file root.crt -keystore servertrust.jks
生成Server端的對外KeyStore。先把根證書放到裏面。 - keytool -importcert -alias servercert -file server.crt -keystore servertrust.jks
把Server證書加到對外KeyStore裏面。