從頭解決PKIX path building failed
從頭解決PKIX path building failed的問題
本篇涉及到PKIX path building failed的原因和解決辦法(包括暫時解決和長效解決的方法),也包括HTTP和HTTPS的區別。
PKIX path building failed 通俗講解。
通俗的講,PKIX path building failed 出現的原因是因爲自己的Java環境沒有相關網站的證書而導致的。
PKIX path building failed 具體內容。
PKIX的全稱爲Public-Key Infrastructure (X.509),通過wiki百科我們可以知道X.509是一種證書的標準,這種標準用在很多網絡協議,比如TLS/SSL。而TLS/SSL是HTTPS協議的標準(HTTPS比HTTP多的部分就在於TLS/SSL),所以本文章我們掌握TLS/SSL的知識。
TLS/SSL協議詳解
接下是TLS和SSL的的關係以及其詳解
TLS和SSL的關係
- SSL 又稱Secure Sockets Layers,而TLS又稱Transport Layer Security。
- TLS位於傳輸層上,而SSL位於傳輸層和應用層之間。
- SSL 總共有3版 分別是 1995年的SSL v1.0, 1995年的SSL v2.0, 1996年的SSL v3.0。
- TLS 目前有四版分別是 1999年的TLS v1.0, 2006年的TLS v1.1, 2008年的TLS v1.2, 2018年的TLS v1.3。
-
SSL 是 TLS 的前身,並且目前已經不推薦使用, TLS v1.0 修正了SSL v3.0中的安全缺陷,但是由於TLS v1.0是可以降級到SSL v3.0所以依舊存在不安全的情況(當你訪問使用較低版本的TLS協議或者任意版本的SSL協議時,你的瀏覽器會提示你,這個時候如果想規避風險,建議就不要繼續了。)
TSL 握手機制。
- TSL handshake
- Client 發送 clientHello 到Sever,內容包括
- 支持的TSL最高版本號
- cipher suite(一堆支持的加密算法)
- 客戶端隨機數
- Server 返回ServerHello 到Client,內容包括
- Server決定的TSL版本號
- 服務器隨機數
- 選擇的cipher suite
- Server發送他的certificate message(這裏包含了server的public-key)到Client,這裏使用證書可以保證public-key是正確的,因爲certificate受到可信部門認證。
- Server發送ServerHelloDone信息到Client,告訴Client他的handshake已結束
- Client 發送ClientKeyExchange message 到 Server。包含:
-
PremasterSecret(這個裏面包含的是sharekey,用server的public加密)。
除此之外,Client使用服務端隨機數,客戶端隨機數,PremasterSecret形成share key
-
- Server使用自己的private key 解密 ClientKeyExchange message,並使用服務端隨機數,客戶端隨機數,PremasterSecret形成share key。
- client 發送ChangeCipherSpec到Server,目的是告訴Server可以開始使用以上協商的share key了。包含
- Finished massage:這個是之前握手信息的hash或者MAC(message authentication code (MAC) algorithm)算法的值
-
Server 收到ChangeCipherSpec,後計算自己本地的內容,檢查收到的hash/mac是否和自己的一致,不一致,這次握手將失敗,一致發送ChangeCipherSpec到client,目的是告訴Client開始使用協商的share key。
cipher suite 詳解
cipher suite 是爲了保證連接過程的安全性,其中包括很4種算法原語的組合。客戶端和服務器handshake時,由服務器確定使用的算法,之後由服務器和客戶端一起使用這樣的算法。
- 四種算法原語(對於一個cipher suite,只能有一個Kx,一個Au一個Enc,一個MAC,但是這些算法可以選擇不同的)
- Key Exchange(Kx),常見DH 和 ECDH,(類似TLS握手機制)
- Authentication (Au),常見DSA/RSA/ECDSA(證書,比如server發送回來的public key 就是放在sever的證書裏的,client可以檢查這個證書是否有效)
- Encryption(Enc),主要AES(加密算法,和密碼學有關,我們此處不談)
- Message Authentication Code(MAC),常見SHA1、SAH256、SHA384(對於message,對整體求hash/md等作爲單獨的tag,即作爲客戶端檢查message完整性和未被篡改的憑證)
解決辦法1(不建議)
之前說過HTTPS的網站纔有TLS/SSL而PKIX在TLS/SSL中使用,所以我們可以利用這種方法,把所有想要訪問的網站的 https://····
換爲 http://····
。
解決方法2(程序內部自動過濾ssl,推薦)
然而有的時候,比如小程序去獲取user的openid和session-key時,需要訪問https://api.weixin.qq.com/sns/jscode2session,此時因爲微信官方的api限制了必須使用https,所以去掉s則會報錯。此時我們採用在本地網絡連接時忽略SSL。
我認爲,在開發軟件時,很多主機如果沒有ssl認證,執行需要的網絡連接就會失敗,所以需要過濾ssl。
可以使用如下的工具類
如需複製代碼請轉到 httpclient 實現https請求
解決辦法3(解決maven等出現pkix的問題)
如圖位置加入 -Dmaven.wagon.http.ssl.insecure=true -Dmaven.wagon.http.ssl.allowall=true
解決方法4 (導入證書)
之前很多博主使用的都不是最新的語法,建議在導入時使用keytool -help看一下最新的導入語法。
cmd在管理員模式進入java jdk 下的jre\lib\security目錄。
我的是C:\Program Files\Java\jdk1.8.0_221\jre\lib\security
獲取證書的方法可以參考其他博主,比較簡單。
使用如下語言導入證書
keytool -importcert -noprompt -trustcacerts -alias xxx(你想要導入的別名) -file "C:\Program Files\Java\jdk1.8.0_221\jre\lib\security\xxx.cer(你的文件的地址)" -keystore "C:\Program Files\Java\jdk1.8.0_221\jre\lib\security\cacerts" -storepass changeit