1. 程式人生 > >Netty及SSL/TLS介紹

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)

  1.      Frame – 物理層
  2.      Ethernet – 資料鏈路層
  3.      Internet Protocol Version – 網路層
  4.     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