從頭解決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
  1. Client 發送 clientHello 到Sever,內容包括
    • 支持的TSL最高版本號
    • cipher suite(一堆支持的加密算法)
    • 客戶端隨機數
  2. Server 返回ServerHello 到Client,內容包括
    • Server決定的TSL版本號
    • 服務器隨機數
    • 選擇的cipher suite
  3. Server發送他的certificate message(這裏包含了server的public-key)到Client,這裏使用證書可以保證public-key是正確的,因爲certificate受到可信部門認證。
  4. Server發送ServerHelloDone信息到Client,告訴Client他的handshake已結束
  5. Client 發送ClientKeyExchange message 到 Server。包含:
    • PremasterSecret(這個裏面包含的是sharekey,用server的public加密)。

      除此之外,Client使用服務端隨機數,客戶端隨機數,PremasterSecret形成share key

  6. Server使用自己的private key 解密 ClientKeyExchange message,並使用服務端隨機數,客戶端隨機數,PremasterSecret形成share key。
  7. client 發送ChangeCipherSpec到Server,目的是告訴Server可以開始使用以上協商的share key了。包含
    • Finished massage:這個是之前握手信息的hash或者MAC(message authentication code (MAC) algorithm)算法的值
  8. 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

相關文章