Netty及SSL/TLS介紹
前言:
蘋果AppStore要求:2017年1月1日起,所有上線蘋果App Store的應用都必須啟用 App Transport Security(ATS)安全功能。AppTransportSecurity(ATS)是蘋果在iOS9中引入的一項隱私保護功能,遮蔽明文HTTP資源載入,連線必須經過更安全的HTTPS協議。據此我們有理由相信:掌握點安全方面的程式設計還是有必要的!
特別說明:本文件主要是為了做一個關於Netty、SSL/TLS方面的概括性介紹,著重於具體編碼實現,文中部分圖片、文字內容來自網路(如有侵權請告知本人刪除),在此也對原文作者表示感謝!
目標:
採用Netty框架,實現SSL/TLS支援,完成Socket服務端和客戶端,以及Http服務端和客戶端的程式開發。(程式碼下載)
一、Netty是什麼
Java的Socket通訊模式經過:BIO(同步阻塞)-> NIO(非阻塞)->AIO(非同步非阻塞)
Netty是一款非同步的事件驅動的網路應用框架和工具,用於快速開發可維護的高效能、高擴充套件性協議伺服器和客戶端。
二、為何用Netty
1、JDK自帶的NIO類庫和API繁雜,使用麻煩,不易開發高質量可靠性程式;而Netty提供的API使用簡單。
2、Netty的功能強大,預置多種編解碼,支援多種協議。
3、定製能力強,可通過ChannelHandler對通訊框架靈活擴充套件。
4、效能高,同其它NIO框架對比,Netty的綜合性能最優。
5、成熟、穩定,已有大規模不同行業的商業應用。
6、社群活躍。
三、Netty應用例子
1、實現Socket通訊服務端和客戶端,具體見程式碼。
2、主要類: Channel、ChannelHandler、ChannelPipeline、ChannelHandlerContext;
其中ChannelHandler又分為ChannelInboundHandler、ChannelOutboundHandler兩大類。
它們關係圖:
(圖1)
(圖2)
(圖3)
三、關於TCP
1、網路分層模型:
(圖4)
(圖5)
2、網路包分析工具:Wireshark
(圖6)
- Frame – 物理層
- Ethernet – 資料鏈路層
- Internet Protocol Version – 網路層
- Transmission Control Protocol – 傳輸層
我們主要關注第四層:傳輸層。
3、TCP三次握手
(圖7)
四、SSL/TSL
SSL是安全套接層(Secure Socket Layer)的縮寫;
TLS表示傳輸層安全(Transport LayerSecurity)的縮寫。
SSL最初由網景公司提出,最初目的是為了保護web安全,現在用來提高傳輸層的安全。
TLS是IETF基於SSLv3制定的標準,兩者基本一致,只有少許的差別。
使用SSL/TLS的通訊,就是為了防止資訊被第三方竊聽、篡改、冒充。
SSLv3/TLS處於傳輸層和應用層之間,分為握手層和記錄層,如下圖所示:
(圖8)
握手過程:
(圖9)
注:Finished亦是Encrypted Handshake Message
這個過程可以通過一個相親過程來“解釋”一下:(做了點添油加醋的步驟:Application Data、Encrypted Alert,但也屬協議的一部分)
(圖10)
說明:Server Key Exchange 跟所選加密演算法有關,如果是RSA演算法則不需要此步驟,若是DSA演算法則需要。certificaterequest、certificate和certificate_verify在雙向認證時才有,其中certificate_verify是客戶端用自己的私鑰簽名前面握手訊息的結果,給服務端認證客戶端的證書certificate是否合法。
五、證書製作
5.1使用keytool自簽名製作證書:
keytool是JDK自帶工具。
5.1.1 單向認證
1) 生成Netty服務端私鑰和證書倉庫命令:
keytool -genkey-alias sserver -keysize 2048 -validity 365 -keyalg RSA -dname "CN=server,OU=HR, O=ESHORE, L=GZ, ST=GD, C=CN" -keypass servers -storepass servers-keystore server_s.jks
2) 生成Netty服務端自簽名證書:
keytool -export-alias sserver -keystore server_s.jks -storepass servers -file server_s.cer
3) 生成客戶端的金鑰對和證書倉庫,命令如下:
keytool -genkey-alias sclient -keysize 2048 -validity 365 -keyalg RSA -dname "CN=client,OU=HR2, O=ESHORE, L=GZ, ST=GD, C=CN" -keypass clients -storepass clients-keystore client_s.jks
4) 將Netty服務端的證書匯入到客戶端的證書倉庫中,命令如下:
keytool -import-trustcacerts -alias sserver -file server_s.cer -storepass clients -keystore client_s.jks
5.1.2 雙向認證(接上面的單向認證)
1) 生成客戶端的自簽名證書:
keytool -export -alias sclient -keystore client_s.jks -storepass clients -file client_s.cer
2) 將客戶端的自簽名證書匯入到服務端的信任證書倉庫中:
keytool -import -trustcacerts -alias sclient -file client_s.cer -storepass servers -keystore server_s.jks
5.2 基於第三方CA認證
需要安裝工具:OpenSSL
先準備必要的目錄和檔案:
mkdir -p ./demoCA/{private,newcerts}
touchdemoCA/index.txt
echo 01 >demoCA/serial
5.1 服務端證書製作:
這裡根據兩種演算法:RSA和DSA 分別建立證書;如果不指明DSA,則屬於RSA建立步驟。
步驟1:利用OpenSSL生成CA證書:
openssl req -new -x509 -keyout ca.key -out ca.crt -days 365
或分步:
openssl genrsa-des3 -out ./demoCA/private/cakey.pem 2048
openssl req -new -days 365 -key ./demoCA/private/cakey.pem -out careq.pem
openssl ca -selfsign -in careq.pem -out ./demoCA/cacert.pem
採用DRA演算法建立:
/*生成1024位的金鑰引數*/
openssl dsaparam-out DSAP.pem 1024
/*生成金鑰並使用des3加密儲存*/
openssl gendsa -out./demoCA/private/cakey_DSA.pem -des3 -passout pass:cakey DSAP.pem
openssl req -new -days 365 -key ./demoCA/private/cakey_DSA.pem -out careq_DSA.pem
/*執行下面命令前,需要把./demoCA/private/cakey_DSA.pem檔名改為cakey.pem */
openssl ca-selfsign -in careq_DSA.pem -out ./demoCA/cacert_DSA.pem
步驟2:生成Netty服務端私鑰和證書倉庫命令:
keytool -genkey -alias sserver -keysize 2048 -validity 365 -keyalg RSA -dname "CN=server,OU=HR, O=ESHORE, L=GZ, ST=GD, C=CN" -keypass serverkey -storepass servers -keystore server.jks
注意:上面命令中,由於-keypass和-storepass 密碼設定不一樣,導致服務端在接收到客戶端連線請求時,報錯:java.security.UnrecoverableKeyException: Cannot recover key
可以通過下面命令,把兩個密碼改為一樣(都為servers),即可解決:
keytool -keypasswd -new servers -keystore server.jks -storepass servers -alias sserver -keypass serverkey
採用DRA演算法建立:
keytool -genkey -alias sserver -keysize 1024 -validity 365 -keyalg DSA -dname "CN=server_DSA, OU=HR, O=ESHORE, L=GZ, ST=GD, C=CN" -keypass servers -storepass servers -keystore server_DSA.jks
步驟3:生成證書籤名請求:
keytool -certreq-alias sserver -sigalg MD5withRSA -file server.csr -keypass serverkey -storepass servers -keystore server.jks
採用DRA演算法建立:
keytool -certreq -alias sserver -sigalg SHA1withDSA -file server_DSA.csr -keypass servers -storepass servers -keystore server_DSA.jks
步驟4:用CA私鑰進行簽名:
openssl ca -inserver.csr -out server.crt
採用DRA演算法建立:
openssl ca -inserver_DSA.csr -out server_DSA.crt -cert ./demoCA/cacert_DSA.pem -keyfile ./demoCA/private/cakey_DSA.pem
步驟5:匯入信任的CA根證書到keystore
keytool -import -v -trustcacerts -alias ca_root -file ./demoCA/cacert.pem -storepass servers -keystore server.jks
採用DRA演算法建立:
keytool -import -v -trustcacerts -alias ca_root -file ./demoCA/cacert_DSA.pem -storepass servers -keystore server_DSA.jks
步驟6:將CA簽名後的server端證書匯入keystore
keytool -import -v -alias sserver -file server.crt -keypass servers -storepass servers -keystore server.jks
採用DRA演算法建立:
keytool -import -v -alias sserver -file server_DSA.crt -keypass servers -storepass servers -keystore server_DSA.jks
5.2 客戶端證書製作:
步驟1:生成客戶端金鑰對:
keytool -genkey -alias sclient -keysize 2048 -validity 365 -keyalg RSA -dname "CN=client,OU=HR2, O=ESHORE, L=GZ, ST=GD, C=CN" -keypass clients -storepass clients-keystore client.jks
採用DRA演算法建立:
keytool -genkey -alias sclient -keysize 1024 -validity 365 -keyalg DSA -dname"CN=client_DSA, OU=HR2, O=ESHORE, L=GZ, ST=GD, C=CN" -keypass clients -storepass clients -keystore client_DSA.jks
步驟2:生成證書籤名請求:
keytool -certreq -alias sclient -sigalg MD5withRSA -file client.csr -keypass clients -storepass clients -keystore client.jks
採用DRA演算法建立:
keytool -certreq -alias sclient -sigalg SHA1withDSA -file client_DSA.csr -keypass clients -storepass clients -keystore client_DSA.jks
步驟3:用CA私鑰進行簽名:
openssl ca -in client.csr -out client.crt
採用DRA演算法建立:
openssl ca -in client_DSA.csr -out client_DSA.crt -cert ./demoCA/cacert_DSA.pem -keyfile ./demoCA/private/cakey_DSA.pem
步驟4:匯入信任的CA根證書到keystore:
keytool -import -v -trustcacerts -alias ca_root -file ./demoCA/cacert.pem -storepass clients -keystore client.jks
採用DRA演算法建立:
keytool -import -v -trustcacerts -alias ca_root -file ./demoCA/cacert_DSA.pem -storepass clients -keystore client_DSA.jks
步驟5:將CA簽名後的client端證書匯入keystore:
keytool -import -v -alias sclient -file client.crt -keypass clients -storepass clients -keystore client.jks
採用DRA演算法建立:
keytool -import -v -alias sclient -file client_DSA.crt -keypass clients -storepass clients -keystore client_DSA.jks
六、參考資料
1、Netty系列之Netty安全性:
2、Netty 各個類的講解:
3、用Wireshark 圖解 TCP 三次握手:
4、SSL協議詳解:
5、使用wireshark觀察SSL/TLS握手過程--雙向認證/單向認證:
6、HTTPS到底是個啥玩意兒:
7、圖解SSL/TLS協議:
8、Handler的執行順序:
9、基於OpenSSL 的 CA 建立及證書籤發:
10、OpenSSL 非對稱加密演算法DSA命令詳解:
--------------------- 本文來自 wujyou 的CSDN 部落格 ,全文地址請點選:https://blog.csdn.net/wujyou/article/details/53816722?utm_source=copy