Netty應(yīng)用示例(二)SSL/TLS應(yīng)用示例

1邪意、SSL/TLS簡(jiǎn)介

協(xié)議是Web瀏覽器與Web服務(wù)器之間安全交換信息的協(xié)議,提供兩個(gè)基本的安全服務(wù):鑒別與保密反砌。

1.1雾鬼、作用

不使用SSL/TLS的HTTP通信,就是不加密的通信宴树。所有信息明文傳播策菜,帶來(lái)了三大風(fēng)險(xiǎn)。

  • 竊聽(tīng)風(fēng)險(xiǎn)(eavesdropping):第三方可以獲知通信內(nèi)容森渐。
  • 篡改風(fēng)險(xiǎn)(tampering):第三方可以修改通信內(nèi)容做入。
  • 冒充風(fēng)險(xiǎn)(pretending):第三方可以冒充他人身份參與通信。

SSL/TLS協(xié)議是為了解決這三大風(fēng)險(xiǎn)而設(shè)計(jì)的同衣,希望達(dá)到:

  • 保密:在握手協(xié)議中定義了會(huì)話密鑰后竟块,所有的消息都被加密。
  • 鑒別:可選的客戶端認(rèn)證耐齐,和強(qiáng)制的服務(wù)器端認(rèn)證浪秘。
  • 完整性:傳送的消息包括消息完整性檢查(使用MAC)。

1.2埠况、工作原理

1.2.1耸携、基本概念

  • Key:Key 是一個(gè)比特(bit)字符串,用來(lái)加密解密數(shù)據(jù)的辕翰,就像是一把開(kāi)鎖的鑰匙夺衍。

  • 對(duì)稱算法(symmetric cryptography):就是需要雙方使用一樣的 key 來(lái)加密解密消息算法,常用密鑰算法有 Data Encryption Standard(DES)喜命、triple-strength DES(3DES)沟沙、Rivest Cipher 2 (RC2)和 Rivest Cipher 4(RC4)。因?yàn)閷?duì)稱算法效率相對(duì)較高壁榕,因此 SSL 會(huì)話中的敏感數(shù)據(jù)都用通過(guò)密鑰算法加密矛紫。

  • 非對(duì)稱算法(asymmetric cryptography):就是 key 的組成是公鑰私鑰對(duì) (key-pair),公鑰傳遞給對(duì)方私鑰自己保留牌里。公鑰私鑰算法是互逆的颊咬,一個(gè)用來(lái)加密,另一個(gè)可以解密牡辽。常用的算法有 Rivest Shamir Adleman(RSA)喳篇、Diffie-Hellman(DH)。非對(duì)稱算法計(jì)算量大比較慢态辛,因此僅適用于少量數(shù)據(jù)加密麸澜,如對(duì)密鑰加密,而不適合大量數(shù)據(jù)的通訊加密因妙。

  • 公鑰證書(public key certificate):公鑰證書類似數(shù)字護(hù)照痰憎,由受信機(jī)構(gòu)頒發(fā)。受信組織的公鑰證書就是 certificate authority(CA)攀涵。多證書可以連接成證書串铣耘,第一個(gè)是發(fā)送人,下一個(gè)是給其頒發(fā)證書實(shí)體以故,往上到根證書是世界范圍受信組織蜗细,包括 VeriSign, Entrust, 和 GTE CyberTrust。公鑰證書讓非對(duì)稱算法的公鑰傳遞更安全怒详,可以避免身份偽造炉媒,比如 C 創(chuàng)建了公鑰私鑰,對(duì)并冒充 A 將公鑰傳遞給 B昆烁,這樣 C 與 B 之間進(jìn)行的通訊會(huì)讓 B 誤認(rèn)是 A 與 B 之間通訊吊骤。

  • 加密哈希功能(Cryptographic Hash Functions):加密哈希功能與 checksum 功能相似。不同之處在于静尼,checksum 用來(lái)偵測(cè)意外的數(shù)據(jù)變化而前者用來(lái)偵測(cè)故意的數(shù)據(jù)篡改白粉。數(shù)據(jù)被哈希后產(chǎn)生一小串比特字符串,微小的數(shù)據(jù)改變將導(dǎo)致哈希串的變化鼠渺。發(fā)送加密數(shù)據(jù)時(shí)鸭巴,SSL 會(huì)使用加密哈希功能來(lái)確保數(shù)據(jù)一致性,用來(lái)阻止第三方破壞通訊數(shù)據(jù)完整性拦盹。SSL 常用的哈希算法有 Message Digest 5(MD5)和 Secure Hash Algorithm(SHA)鹃祖。

  • 消息認(rèn)證碼(Message Authentication Code):消息認(rèn)證碼與加密哈希功能相似,除了它需要基于密鑰普舆。密鑰信息與加密哈希功能產(chǎn)生的數(shù)據(jù)結(jié)合就是哈希消息認(rèn)證碼(HMAC)恬口。如果 A 要確保給 B 發(fā)的消息不被 C 篡改,他要按如下步驟做 --A 首先要計(jì)算出一個(gè) HMAC 值奔害,將其添加到原始消息后面楷兽。用 A 與 B 之間通訊的密鑰加密消息體,然后發(fā)送給 B华临。B 收到消息后用密鑰解密芯杀,然后重新計(jì)算出一個(gè) HMAC,來(lái)判斷消息是否在傳輸中被篡改雅潭。SSL 用 HMAC 來(lái)保證數(shù)據(jù)傳輸?shù)陌踩?/p>

  • 數(shù)字簽名(Digital Signature):一個(gè)消息的加密哈希被創(chuàng)建后揭厚,哈希值用發(fā)送者的私鑰加密,加密的結(jié)果就是叫做數(shù)字簽名扶供。

1.2.2筛圆、認(rèn)證類型:

  • 單向認(rèn)證:就是用戶到服務(wù)器之間只存在單方面的認(rèn)證,即客戶端會(huì)認(rèn)證服務(wù)器端身份椿浓,而服務(wù)器端不會(huì)去對(duì)客戶端身份進(jìn)行驗(yàn)證太援。首先闽晦,客戶端發(fā)起握手請(qǐng)求,服務(wù)器收到握手請(qǐng)求后提岔,會(huì)選擇適合雙方的協(xié)議版本和加密方式仙蛉。然后,再將協(xié)商的結(jié)果和服務(wù)器端的公鑰一起發(fā)送給客戶端碱蒙≤瘢客戶端利用服務(wù)器端的公鑰,對(duì)要發(fā)送的數(shù)據(jù)進(jìn)行加密赛惩,并發(fā)送給服務(wù)器端哀墓。服務(wù)器端收到后,會(huì)用本地私鑰對(duì)收到的客戶端加密數(shù)據(jù)進(jìn)行解密喷兼。然后篮绰,通訊雙方都會(huì)使用這些數(shù)據(jù)來(lái)產(chǎn)生雙方之間通訊的加密密鑰。接下來(lái)季惯,雙方就可以開(kāi)始安全通訊過(guò)程了阶牍。
  • 雙向認(rèn)證:就是雙方都會(huì)互相認(rèn)證,也就是兩者之間將會(huì)交換證書星瘾∽吣酰基本的過(guò)程和單向認(rèn)證完全一樣,只是在協(xié)商階段多了幾個(gè)步驟琳状。在服務(wù)器端將協(xié)商的結(jié)果和服務(wù)器端的公鑰一起發(fā)送給客戶端后磕瓷,會(huì)請(qǐng)求客戶端的證書,客戶端則會(huì)將證書發(fā)送給服務(wù)器端念逞。然后困食,在客戶端給服務(wù)器端發(fā)送加密數(shù)據(jù)后,客戶端會(huì)將私鑰生成的數(shù)字簽名發(fā)送給服務(wù)器端翎承。而服務(wù)器端則會(huì)用客戶端證書中的公鑰來(lái)驗(yàn)證數(shù)字簽名的合法性硕盹。建立握手之后過(guò)程則和單向通訊完全保持一致。

1.2.3叨咖、握手協(xié)議(Handshake protocol)

握手流程:

握手流程.png

步驟 1:ClientHello – 客戶端發(fā)送所支持的 SSL/TLS 最高協(xié)議版本號(hào)和所支持的加密算法集合及壓縮方法集合等信息給服務(wù)器端瘩例。
步驟 2.:ServerHello – 服務(wù)器端收到客戶端信息后,選定雙方都能夠支持的 SSL/TLS 協(xié)議版本和加密方法及壓縮方法甸各,返回給客戶端垛贤。
步驟 3.:SendCertificate(可選) – 服務(wù)器端發(fā)送服務(wù)端證書給客戶端。
步驟 4: RequestCertificate(可選) – 如果選擇雙向驗(yàn)證趣倾,服務(wù)器端向客戶端請(qǐng)求客戶端證書聘惦。
步驟 5.:ServerHelloDone – 服務(wù)器端通知客戶端初始協(xié)商結(jié)束。
步驟 6.:ResponseCertificate(可選) – 如果選擇雙向驗(yàn)證儒恋,客戶端向服務(wù)器端發(fā)送客戶端證書善绎。
步驟 7.:ClientKeyExchange – 客戶端使用服務(wù)器端的公鑰黔漂,對(duì)客戶端公鑰和密鑰種子進(jìn)行加密禀酱,再發(fā)送給服務(wù)器端瘟仿。
步驟 8:CertificateVerify(可選) – 如果選擇雙向驗(yàn)證,客戶端用本地私鑰生成數(shù)字簽名比勉,并發(fā)送給服務(wù)器端,讓其通過(guò)收到的客戶端公鑰進(jìn)行身份驗(yàn)證驹止。
步驟 9: CreateSecretKey – 通訊雙方基于密鑰種子等信息生成通訊密鑰浩聋。
步驟 10: ChangeCipherSpec – 客戶端通知服務(wù)器端已將通訊方式切換到加密模式。
步驟 11:Finished – 客戶端做好加密通訊的準(zhǔn)備臊恋。
步驟 12:ChangeCipherSpec – 服務(wù)器端通知客戶端已將通訊方式切換到加密模式衣洁。
步驟 13:Finished – 服務(wù)器做好加密通訊的準(zhǔn)備。
步驟 14:Encrypted/DecryptedData – 雙方使用客戶端密鑰抖仅,通過(guò)對(duì)稱加密算法對(duì)通訊內(nèi)容進(jìn)行加密坊夫。
步驟 15:ClosedConnection – 通訊結(jié)束后,任何一方發(fā)出斷開(kāi) SSL 連接的消息撤卢。

1.2.4环凿、記錄協(xié)議(Record protocol)

記錄協(xié)議在客戶機(jī)和服務(wù)器握手成功后使用,即客戶機(jī)和服務(wù)器鑒別對(duì)方和確定安全信息交換使用的算法后放吩,進(jìn)入SSL記錄協(xié)議智听,記錄協(xié)議向SSL連接提供兩個(gè)服務(wù):

  • 保密性:使用握手協(xié)議定義的秘密密鑰實(shí)現(xiàn)
  • 完整性:握手協(xié)議定義了MAC,用于保證消息完整性

記錄協(xié)議的過(guò)程:

記錄協(xié)議的過(guò)程.png

1.2.5渡紫、報(bào)警協(xié)議(Alert protocol)

客戶機(jī)和服務(wù)器發(fā)現(xiàn)錯(cuò)誤時(shí)到推,向?qū)Ψ桨l(fā)送一個(gè)警報(bào)消息。如果是致命錯(cuò)誤惕澎,則算法立即關(guān)閉SSL連接莉测,雙方還會(huì)先刪除相關(guān)的會(huì)話號(hào),秘密和密鑰唧喉。每個(gè)警報(bào)消息共2個(gè)字節(jié)捣卤,第1個(gè)字節(jié)表示錯(cuò)誤類型,如果是警報(bào)八孝,則值為1腌零,如果是致命錯(cuò)誤,則值為2唆阿;第2個(gè)字節(jié)制定實(shí)際錯(cuò)誤類型益涧。

1.2.6、秘鑰生成過(guò)程

這樣握手協(xié)議完成驯鳖,下面看下什么是預(yù)備主密鑰闲询,主密鑰是怎么生成的久免。為了保證信息的完整性和機(jī)密性,SSL需要有六個(gè)加密秘密:四個(gè)密鑰和兩個(gè)IV扭弧。為了信息的可信性阎姥,客戶端需要一個(gè)密鑰(HMAC),為了加密要有一個(gè)密鑰鸽捻,為了分組加密要一個(gè)IV呼巴,服務(wù)也是如此。SSL需要的密鑰是單向的御蒲,不同于那些在其他方向的密鑰衣赶。如果在一個(gè)方向上有攻擊,這種攻擊在其他方向是沒(méi)影響的厚满。生成過(guò)程如下:

從預(yù)備主秘鑰計(jì)算主秘鑰.png
從主秘鑰計(jì)算秘鑰材料.png

從秘鑰材料提取加密秘鑰.png

參考博客:

http://www.ruanyifeng.com/blog/2014/02/ssl_tls.html
https://segmentfault.com/a/1190000002554673
https://www.ibm.com/developerworks/cn/java/j-lo-ssltls/index.html
https://www.cnblogs.com/zhuqil/archive/2012/10/06/ssl_detail.html
https://www.cnblogs.com/zhuqil/archive/2012/10/06/ssl_detail.html

2府瞄、keytool簡(jiǎn)介

Java自帶的keytool工具是個(gè)密鑰和證書管理工具。它使用戶能夠管理自己的公鑰/私鑰對(duì)及相關(guān)證書碘箍,用于(通過(guò)數(shù)字簽名)自我認(rèn)證(用戶向別的用戶/服務(wù)認(rèn)證自己)或數(shù)據(jù)完整性以及認(rèn)證服務(wù)遵馆。它還允許用戶儲(chǔ)存他們的通信對(duì)等者的公鑰(以證書形式)。 keytool 將密鑰和證書儲(chǔ)存在一個(gè)所謂的密鑰倉(cāng)庫(kù)(keystore)中丰榴。缺省的密鑰倉(cāng)庫(kù)實(shí)現(xiàn)將密鑰倉(cāng)庫(kù)實(shí)現(xiàn)為一個(gè)文件货邓。它用口令來(lái)保護(hù)私鑰。

2.1四濒、Java KeyStore的類型

  • JKS和JCEKS是Java密鑰庫(kù)(KeyStore)的兩種比較常見(jiàn)類型(我所知道的共有5種逻恐,JKS, JCEKS, PKCS12, BKS,UBER)峻黍。
  • JKS的Provider是SUN复隆,在每個(gè)版本的JDK中都有,JCEKS的Provider是SUNJCE姆涩,1.4后我們都能夠直接使用它挽拂。
  • JCEKS在安全級(jí)別上要比JKS強(qiáng),使用的Provider是JCEKS(推薦)骨饿,尤其在保護(hù)KeyStore中的私鑰上(使用TripleDes)亏栈。
  • PKCS#12是公鑰加密標(biāo)準(zhǔn),它規(guī)定了可包含所有私鑰宏赘、公鑰和證書绒北。其以二進(jìn)制格式存儲(chǔ),也稱為 PFX 文件察署,在windows中可以直接導(dǎo)入到密鑰區(qū)闷游,注意,PKCS#12的密鑰庫(kù)保護(hù)密碼同時(shí)也用于保護(hù)Key。
  • BKS 來(lái)自BouncyCastle Provider脐往,它使用的也是TripleDES來(lái)保護(hù)密鑰庫(kù)中的Key休吠,它能夠防止證書庫(kù)被不小心修改(Keystore的keyentry改掉1個(gè) bit都會(huì)產(chǎn)生錯(cuò)誤),BKS能夠跟JKS互操作业簿,讀者可以用Keytool去TryTry瘤礁。
  • UBER比較特別,當(dāng)密碼是通過(guò)命令行提供的時(shí)候梅尤,它只能跟keytool交互柜思。整個(gè)keystore是通過(guò)PBE/SHA1/Twofish加密,因此keystore能夠防止被誤改巷燥、察看以及校驗(yàn)赡盘。以前,Sun JDK(提供者為SUN)允許你在不提供密碼的情況下直接加載一個(gè)Keystore矾湃,類似cacerts,UBER不允許這種情況堕澄。

2.2邀跃、keytool的命令

  • -genkey:在用戶主目錄中創(chuàng)建一個(gè)默認(rèn)文件".keystore",還會(huì)產(chǎn)生一個(gè)mykey的別名,mykey中包含用戶的公鑰蛙紫、私鑰和證書拍屑,(默認(rèn)情況下,keystore會(huì)存在用戶系統(tǒng)默認(rèn)目錄,如:win系統(tǒng)坑傅,會(huì)生成在C:\Documents and Settings\用戶名\文件名為“.keystore”)僵驰;
  • -keystore:指定密鑰庫(kù)的名稱(產(chǎn)生的各類信息將不在.keystore文件中);
  • -keyalg:指定密鑰的算法 (如RSA唁毒、DSA蒜茴,default:DSA);
  • -validity:指定創(chuàng)建的證書有效期多少天(default:90)浆西;
  • -keysize:指定密鑰長(zhǎng)度(default:1024粉私,范圍:512 ~ 2048);
  • -storepass:指定密鑰庫(kù)的密碼(獲取keystore信息所需的密碼)近零;
  • -keypass:指定別名條目的密碼(私鑰的密碼)诺核;
  • -dname:指定證書擁有者信息。例如: "CN=名字與姓氏,OU=組織單位名稱,O=組織名稱,L=城市或區(qū)域名稱,ST=州或省份名稱,C=單位的兩字母國(guó)家代碼"久信;
  • -list:顯示密鑰庫(kù)中的證書信息窖杀。keytool -list -v -keystore 指定keystore -storepass 密碼 -v 顯示密鑰庫(kù)中的證書詳細(xì)信息;
  • -export:將別名指定的證書導(dǎo)出到文件裙士。keytool -export -alias 需要導(dǎo)出的別名 -keystore 指定keystore -file 指定導(dǎo)出的證書位置及證書名稱 -storepass 密碼入客;
  • -delete:刪除密鑰庫(kù)中某條目。keytool -delete -alias 指定需刪除的keystore別名 -keystore 指定keystore -storepass 密碼;
  • -printcert:查看導(dǎo)出的證書信息痊项。keytool -printcert -file yushan.crt锅风;
  • -keypasswd:修改密鑰庫(kù)中指定條目口令。keytool -keypasswd -alias 需修改的別名 -keypass 舊密碼 -new 新密碼 -storepass keystore密碼 -keystore sage鞍泉;
  • -storepasswd:修改keystore口令皱埠。keytool -storepasswd -keystore e:\yushan.keystore(需修改口令的keystore) -storepass 123456(原始密碼) -new yushan(新密碼);
  • -import:將已簽名數(shù)字證書導(dǎo)入密鑰庫(kù)咖驮。keytool -import -alias 別名 -keystore指定keystore -file需導(dǎo)入的證書边器;

2.3、keytool使用示例

2.3.1托修、keystone的生成

分階段生成:

命令:

keytool -genkey -alias zhaozhou -keypass zhaozhou -keyalg RSA -keysize 1024 -validity 365 -keystore testStore.keystore -storepass 666666

您的名字與姓氏是什么?
[Unknown]: zhaozhou
您的組織單位名稱是什么?
[Unknown]: jd
您的組織名稱是什么?
[Unknown]: jd
您所在的城市或區(qū)域名稱是什么?
[Unknown]: beijing
您所在的省/市/自治區(qū)名稱是什么?
[Unknown]: beijing
該單位的雙字母國(guó)家/地區(qū)代碼是什么?
[Unknown]: ch
CN=zhaozhou, OU=jd, O=jd, L=beijing, ST=beijing, C=ch是否正確?
[否]: y

一次性生成:
命令:

keytool -genkey -alias zhaozhou -keypass zhaozhou -keyalg RSA -keysize 1024 -validity 365 -keystore testStore.keystore -storepass 666666 -dname "CN=zhaozhou, OU=jd, O=jd, L=beijing, ST=beijing, C=ch"

2.3.2忘巧、keystore信息的查看

命令:

keytool -list -v -keystore testStore.keystore -storepass 666666

輸出:

密鑰庫(kù)類型: JKS
密鑰庫(kù)提供方: SUN

您的密鑰庫(kù)包含 1 個(gè)條目

別名: zhaozhou
創(chuàng)建日期: 2019-1-5
條目類型: PrivateKeyEntry
證書鏈長(zhǎng)度: 1
證書[1]:
所有者: CN=zhaozhou, OU=jd, O=jd, L=beijing, ST=beijing, C=ch
發(fā)布者: CN=zhaozhou, OU=jd, O=jd, L=beijing, ST=beijing, C=ch
序列號(hào): ab89854
有效期開(kāi)始日期: Sat Jan 05 14:59:54 CST 2019, 截止日期: Sun Jan 05 14:59:54 CST
2020
證書指紋:
         MD5: 9D:F0:98:56:3F:F7:9C:38:58:FC:30:3C:2B:28:24:2E
         SHA1: AC:74:9E:A5:41:AD:D6:F7:E1:6E:5E:F9:FD:96:49:FD:E4:E0:D9:C5
         SHA256: CE:77:51:60:00:CB:DF:D5:AE:EA:5D:4F:5C:85:47:14:D9:5A:56:72:66:
F1:A8:E8:8D:1D:E9:50:CC:3B:81:1A
         簽名算法名稱: SHA256withRSA
         版本: 3

擴(kuò)展:

#1: ObjectId: 2.5.29.14 Criticality=false
SubjectKeyIdentifier [
KeyIdentifier [
0000: 19 0A A6 EB 67 E9 B8 5B   F5 58 03 2D B9 5D E8 93  ....g..[.X.-.]..
0010: CD 4B B1 98                                        .K..
]
]



*******************************************
*******************************************

2.3.3、證書導(dǎo)出

命令:

keytool -export -alias zhaozhou -keystore testStore.keystore -storepass 666666 -file testStore.cer

輸出:

存儲(chǔ)在文件 <testStore.cer> 中的證書

2.3.4睦刃、證書確認(rèn)

命令:

keytool -printcert -file testStore.cer

輸出:

所有者: CN=zhaozhou, OU=jd, O=jd, L=beijing, ST=beijing, C=ch
發(fā)布者: CN=zhaozhou, OU=jd, O=jd, L=beijing, ST=beijing, C=ch
序列號(hào): ab89854
有效期開(kāi)始日期: Sat Jan 05 14:59:54 CST 2019, 截止日期: Sun Jan 05 14:59:54 CST
2020
證書指紋:
         MD5: 9D:F0:98:56:3F:F7:9C:38:58:FC:30:3C:2B:28:24:2E
         SHA1: AC:74:9E:A5:41:AD:D6:F7:E1:6E:5E:F9:FD:96:49:FD:E4:E0:D9:C5
         SHA256: CE:77:51:60:00:CB:DF:D5:AE:EA:5D:4F:5C:85:47:14:D9:5A:56:72:66:
F1:A8:E8:8D:1D:E9:50:CC:3B:81:1A
         簽名算法名稱: SHA256withRSA
         版本: 3

擴(kuò)展:

#1: ObjectId: 2.5.29.14 Criticality=false
SubjectKeyIdentifier [
KeyIdentifier [
0000: 19 0A A6 EB 67 E9 B8 5B   F5 58 03 2D B9 5D E8 93  ....g..[.X.-.]..
0010: CD 4B B1 98                                        .K..
]
]

2.3.5砚嘴、證書導(dǎo)入

命令:

keytool -import -alias client -file client.cer -keystore testStore.keystore -storepass 666666 -keypass 666666

輸出:

所有者: CN=localhost
發(fā)布者: CN=localhost
序列號(hào): 5b1bd334
有效期開(kāi)始日期: Fri Jan 04 20:26:42 CST 2019, 截止日期: Sat Jan 04 20:26:42 CST
2020
證書指紋:
         MD5: A1:F3:B4:96:42:E9:62:2B:8C:FB:83:3B:E2:EE:A3:29
         SHA1: 33:01:EA:A6:12:EF:E3:8E:4C:CA:11:EF:D9:4D:DF:3D:85:93:7D:29
         SHA256: 1F:EE:BF:D3:15:78:E2:34:F5:53:0E:49:43:58:0E:BB:3E:A5:EE:22:0E:
D1:82:42:95:CD:19:FA:B1:03:7D:74
         簽名算法名稱: SHA256withRSA
         版本: 3

擴(kuò)展:

#1: ObjectId: 2.5.29.14 Criticality=false
SubjectKeyIdentifier [
KeyIdentifier [
0000: 23 9D 32 A9 0F C6 C1 1B   95 57 16 88 20 3E B7 0C  #.2......W.. >..
0010: 2B 8D 21 59                                        +.!Y
]
]

是否信任此證書? [否]:  y
證書已添加到密鑰庫(kù)中

2.3.6、刪除證書

命令:

keytool -delete -alias zhaozhou -keystore testStore.keystore -storepass 666666

輸出:

參考博客:

http://tutorials.jenkov.com/java-cryptography/keystore.html
https://www.cnblogs.com/littleatp/p/5922362.html
https://czj4451.iteye.com/blog/1487684
https://my.oschina.net/suyewanwan/blog/164108
https://my.oschina.net/u/2502527/blog/596425
https://my.oschina.net/xinxingegeya/blog/264635
https://www.chinassl.net/ssltools/keytool-commands.html
http://www.cnblogs.com/xdp-gacl/p/3750965.html
https://blog.csdn.net/liumiaocn/article/details/61921014

3涩拙、Netty+TLS的加密通信

3.1际长、單向認(rèn)證

3.1.1、秘鑰及簽名證書生成

(1)生成Netty服務(wù)器公鑰兴泥、私鑰和證書倉(cāng)庫(kù):

keytool -genkey -alias server -keysize 2048 -validity 3650 -keyalg RSA -dname "CN=localhost" -keypass nettyDemo -storepass nettyDemo -keystore serverStore.jks

說(shuō)明:
-alias server:服務(wù)器證書倉(cāng)庫(kù)關(guān)聯(lián)的別名為
-keypass nettyDemo:服務(wù)器私鑰密碼
-storepass nettyDemo:服務(wù)器秘鑰庫(kù)密碼
-keystore serverStore.jks:服務(wù)器秘鑰庫(kù)的文件名(默認(rèn)放在用戶主目錄下)

(2)導(dǎo)出Netty服務(wù)端簽名證書:

keytool -export -alias server -keystore serverStore.jks -storepass nettyDemo -file server.cer

(3)生成Netty客戶端的公鑰工育、私鑰和證書倉(cāng)庫(kù):

keytool -genkey -alias client -keysize 2048 -validity 3650 -keyalg RSA -dname "CN=localhost" -keypass nettyDemo -storepass nettyDemo -keystore clientStore.jks

說(shuō)明:

-alias client:客戶端證書倉(cāng)庫(kù)關(guān)聯(lián)的別名;

-keypass nettyDemo:客戶端私鑰密碼搓彻;

-storepass nettyDemo:客戶端秘鑰庫(kù)密碼

-keystore clientStore.jks:客戶端秘鑰庫(kù)的文件名(默認(rèn)放在用戶主目錄下)

(4)將Netty服務(wù)端的證書導(dǎo)入到客戶端的證書倉(cāng)庫(kù)中:

keytool -import -trustcacerts -alias server -file server.cer -storepass nettyDemo -keystore clientStore.jks

最終生成文件:

  • conf/oneway/clientStore.jks:客戶端的證書倉(cāng)庫(kù)(包含公鑰如绸、私鑰、信任的證書倉(cāng)庫(kù)(服務(wù)端的證書))
  • conf/oneway/serverStore.jks:服務(wù)端的證書倉(cāng)庫(kù)(包含公鑰旭贬、私鑰怔接、信任的證書倉(cāng)庫(kù)(無(wú)證書))
  • conf/oneway/server.cer:服務(wù)端字簽名證書的導(dǎo)出文件

3.1.2、源碼示例

(1)稀轨、代碼目錄

源碼目錄.png

clientStore.jks為客戶端的秘鑰庫(kù)蜕提,serverStore.jks為服務(wù)端的秘鑰庫(kù),server.cer為服務(wù)端的公鑰靶端;

單向認(rèn)證示例源碼:https://github.com/zhaozhou11/netty-demo.git

(2)谎势、服務(wù)端SSLContext生成

public static SSLContext getServerContext(String pkPath){
   if(SERVER_CONTEXT!=null) return SERVER_CONTEXT;
   InputStream in =null;
   
   try{
      //密鑰管理器
      KeyManagerFactory kmf = null;
      if(pkPath!=null){
         //密鑰庫(kù)KeyStore
         KeyStore ks = KeyStore.getInstance("JKS");
         //加載服務(wù)端證書
         in = new FileInputStream(pkPath);
         //加載服務(wù)端的KeyStore  ;sNetty是生成倉(cāng)庫(kù)時(shí)設(shè)置的密碼杨名,用于檢查密鑰庫(kù)完整性的密碼
         ks.load(in, "nettyDemo".toCharArray());
         
         kmf = KeyManagerFactory.getInstance("SunX509");
         //初始化密鑰管理器
         kmf.init(ks, "nettyDemo".toCharArray());
      }
      //獲取安全套接字協(xié)議(TLS協(xié)議)的對(duì)象
      SERVER_CONTEXT= SSLContext.getInstance(PROTOCOL);
      //初始化此上下文
      //參數(shù)一:認(rèn)證的密鑰      參數(shù)二:對(duì)等信任認(rèn)證  參數(shù)三:偽隨機(jī)數(shù)生成器 脏榆。 由于單向認(rèn)證,服務(wù)端不用驗(yàn)證客戶端台谍,所以第二個(gè)參數(shù)為null
      SERVER_CONTEXT.init(kmf.getKeyManagers(), null, null);
      
   }catch(Exception e){
      throw new Error("Failed to initialize the server-side SSLContext", e);
   }finally{
      if(in !=null){
         try {
            in.close();
         } catch (IOException e) {
            e.printStackTrace();
         }
      }
      
   }
   return SERVER_CONTEXT;
 }

(3)须喂、客戶端SSLContext生成:

public static SSLContext getClientContext(String caPath){
 if(CLIENT_CONTEXT!=null) return CLIENT_CONTEXT;
 
 InputStream tIN = null;
 try{
    //信任庫(kù) 
   TrustManagerFactory tf = null;
   if (caPath != null) {
      //密鑰庫(kù)KeyStore
       KeyStore tks = KeyStore.getInstance("JKS");
       //加載客戶端證書
       tIN = new FileInputStream(caPath);
       tks.load(tIN, "nettyDemo".toCharArray());
       tf = TrustManagerFactory.getInstance("SunX509");
       // 初始化信任庫(kù)  
       tf.init(tks);
   }
    
    CLIENT_CONTEXT = SSLContext.getInstance(PROTOCOL);
    //設(shè)置信任證書
    CLIENT_CONTEXT.init(null,tf == null ? null : tf.getTrustManagers(), null);
    
 }catch(Exception e){
    throw new Error("Failed to initialize the client-side SSLContext");
 }finally{
    if(tIN !=null){
         try {
            tIN.close();
         } catch (IOException e) {
            e.printStackTrace();
         }
      }
 }
 
 return CLIENT_CONTEXT;
}

(4)服務(wù)端ChannelHandler初始化:

ChannelPipeline pipeline = sc.pipeline();
String sChatPath = (System.getProperty("user.dir")+ "/src/main/java/com/zhaozhou/netty/demo/ssl/conf/oneway/serverStore.jks");

SSLEngine engine = SslOneWayContextFactory.getServerContext(sChatPath).createSSLEngine();
engine.setUseClientMode(false);//設(shè)置為服務(wù)器模式
//engine.setNeedClientAuth(false);//不需要客戶端認(rèn)證,默認(rèn)為false,故不需要寫這行坞生。

pipeline.addLast("ssl", new SslHandler(engine));

// On top of the SSL handler, add the text line codec.
pipeline.addLast("framer", new LineBasedFrameDecoder(1024, false, false));
pipeline.addLast("decoder", new StringDecoder());
pipeline.addLast("encoder", new StringEncoder());

// and then business logic.
pipeline.addLast("handler", new SslOneWayServerHandler());

(5)仔役、服務(wù)端ChannelHandler初始化:

ChannelPipeline pipeline = ch.pipeline();
String cChatPath =  System.getProperty("user.dir")+"/src/main/java/com/zhaozhou/netty/demo/ssl/conf/oneway/clientStore.jks";

SSLEngine engine = SslOneWayContextFactory.getClientContext(cChatPath)
      .createSSLEngine();//創(chuàng)建SSLEngine
engine.setUseClientMode(true);//客戶方模式
pipeline.addLast("ssl", new SslHandler(engine));

// On top of the SSL handler, add the text line codec.
pipeline.addLast("framer", new LineBasedFrameDecoder(1024, false, false));
pipeline.addLast("decoder", new StringDecoder());
pipeline.addLast("encoder", new StringEncoder());

// and then business logic.
pipeline.addLast("handler", new SslOneWayClientHandler());

(6)、測(cè)試輸出

服務(wù)端輸出:

單向服務(wù)端輸出.png

客戶端輸出:

單向客戶端輸出.png

3.2是己、雙向認(rèn)證

3.2.1又兵、秘鑰及簽名證書生成

雙向認(rèn)證的前面4步和單向認(rèn)證的一樣,雙向認(rèn)證多兩步卒废,需導(dǎo)出客戶端公鑰并將客戶端公鑰導(dǎo)入服務(wù)端的證書倉(cāng)庫(kù):

(5)沛厨、導(dǎo)出Netty的客戶端的自簽名證書:

keytool -export -alias client -keystore clientStore.jks -storepass nettyDemo -file client.cer

(6)、將客戶端的自簽名證書導(dǎo)入到服務(wù)器的證書倉(cāng)庫(kù)中:

keytool -import -trustcacerts -alias client -file client.cer -storepass nettyDemo -keystore serverStore.jks

3.2.2摔认、源碼示例

雙向認(rèn)證的源碼示例與單向認(rèn)證基本相同逆皮,在此不多贅述。

雙向認(rèn)證示例源碼:https://github.com/zhaozhou11/netty-demo.git

3.2.3参袱、測(cè)試輸出

服務(wù)端輸出:

雙向服務(wù)端輸出.png

客戶端輸出:

雙向客戶端輸出.png

參考博客:

https://blog.csdn.net/zhixinhuacom/article/details/79097737
https://blog.csdn.net/zhixinhuacom/article/details/79126274
https://my.oschina.net/xinxingegeya/blog/267804
https://www.cnblogs.com/liuroy/p/7435356.html
https://dwj147258.iteye.com/blog/2339934
https://dwj147258.iteye.com/blog/2360535
https://blog.csdn.net/virgilli/article/details/42836063
https://waylau.gitbooks.io/essential-netty-in-action/CORE%20FUNCTIONS/Securing%20Netty%20applications%20with%20SSLTLS.html

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末电谣,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子抹蚀,更是在濱河造成了極大的恐慌剿牺,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,214評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件况鸣,死亡現(xiàn)場(chǎng)離奇詭異牢贸,居然都是意外死亡竹观,警方通過(guò)查閱死者的電腦和手機(jī)镐捧,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,307評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)臭增,“玉大人懂酱,你說(shuō)我怎么就攤上這事√芘祝” “怎么了列牺?”我有些...
    開(kāi)封第一講書人閱讀 152,543評(píng)論 0 341
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)拗窃。 經(jīng)常有香客問(wèn)我瞎领,道長(zhǎng),這世上最難降的妖魔是什么随夸? 我笑而不...
    開(kāi)封第一講書人閱讀 55,221評(píng)論 1 279
  • 正文 為了忘掉前任九默,我火速辦了婚禮,結(jié)果婚禮上宾毒,老公的妹妹穿的比我還像新娘驼修。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,224評(píng)論 5 371
  • 文/花漫 我一把揭開(kāi)白布乙各。 她就那樣靜靜地躺著墨礁,像睡著了一般。 火紅的嫁衣襯著肌膚如雪耳峦。 梳的紋絲不亂的頭發(fā)上恩静,一...
    開(kāi)封第一講書人閱讀 49,007評(píng)論 1 284
  • 那天,我揣著相機(jī)與錄音妇萄,去河邊找鬼蜕企。 笑死,一個(gè)胖子當(dāng)著我的面吹牛冠句,可吹牛的內(nèi)容都是我干的轻掩。 我是一名探鬼主播,決...
    沈念sama閱讀 38,313評(píng)論 3 399
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼懦底,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼唇牧!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起聚唐,我...
    開(kāi)封第一講書人閱讀 36,956評(píng)論 0 259
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤丐重,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后杆查,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體扮惦,經(jīng)...
    沈念sama閱讀 43,441評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,925評(píng)論 2 323
  • 正文 我和宋清朗相戀三年亲桦,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了崖蜜。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,018評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡客峭,死狀恐怖豫领,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情舔琅,我是刑警寧澤等恐,帶...
    沈念sama閱讀 33,685評(píng)論 4 322
  • 正文 年R本政府宣布,位于F島的核電站备蚓,受9級(jí)特大地震影響课蔬,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜郊尝,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,234評(píng)論 3 307
  • 文/蒙蒙 一二跋、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧虚循,春花似錦同欠、人聲如沸样傍。這莊子的主人今日做“春日...
    開(kāi)封第一講書人閱讀 30,240評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)衫哥。三九已至,卻和暖如春襟锐,著一層夾襖步出監(jiān)牢的瞬間撤逢,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書人閱讀 31,464評(píng)論 1 261
  • 我被黑心中介騙來(lái)泰國(guó)打工粮坞, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留蚊荣,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 45,467評(píng)論 2 352
  • 正文 我出身青樓莫杈,卻偏偏與公主長(zhǎng)得像互例,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子筝闹,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,762評(píng)論 2 345

推薦閱讀更多精彩內(nèi)容

  • 互聯(lián)網(wǎng)的通信安全媳叨,建立在SSL/TLS協(xié)議之上。 本文簡(jiǎn)要介紹SSL/TLS協(xié)議的運(yùn)行機(jī)制关顷。文章的重點(diǎn)是設(shè)計(jì)思想和...
    拉肚閱讀 2,617評(píng)論 0 6
  • 本文轉(zhuǎn)載糊秆,出處如下:數(shù)字證書原理 文中首先解釋了加密解密的一些基礎(chǔ)知識(shí)和概念,然后通過(guò)一個(gè)加密通信過(guò)程的例子說(shuō)明了...
    隨安居士閱讀 1,673評(píng)論 1 8
  • 服務(wù)器https配置 配置https操作說(shuō)明文檔 1议双、查看服務(wù)器環(huán)境配置(tomcat和apache合并使用) 2...
    南京楊小兵閱讀 8,806評(píng)論 0 9
  • 根證書含義 - 孤舟蓑笠翁痘番,獨(dú)釣寒江雪 - 博客頻道 - CSDN.NET 本文想簡(jiǎn)單談?wù)勀莻€(gè)所謂的...
    拉肚閱讀 2,371評(píng)論 0 1
  • 數(shù)字證書原理 - 無(wú)恙 - 博客園 文中首先解釋了加密解密的一些基礎(chǔ)知識(shí)和概念,然后通過(guò)一個(gè)加密通信過(guò)程的例子說(shuō)明...
    拉肚閱讀 1,657評(píng)論 0 3