2012-07-31 134 views
17

我正在構建一個簡單的應用程序監視器來輪詢我們的一個API URL併發送給我們,如果它無法從響應中獲取HTTP 200狀態代碼(這將表明我們的API由於某種原因而下降)。SSL HttpClient 4.1的「Peer Not Authenticated」錯誤

我使用的HttpClient 4.1 (這是重要的,因爲它的API從3.x的不同大大)。

我們的API是安全與SSL,但是進入:

http://example.com/our-api

到Web瀏覽器重定向到

https://example.com/our-api

不會造成任何錯誤。

當HttpClient的嘗試打這個URL(http://example.com/our-api),它失敗了javax.net.ssl.SSLPeerUnverifiedException異常有消息指出:

對未通過身份驗證

我看到這種情況出現了很多其他人正如this的帖子所證明的那樣(這也提供了一些方法來規避這個問題 - 事實上,我將在今晚嘗試和實施這個解決方案)。

這篇帖子(和其他類似的帖子)沒有做的是解釋爲什麼這首先發生!所以,而不是問「我該如何解決這個問題?」我想我會問「爲什麼會發生這種情況?」在我提出解決方案之一繼續前進之前,我想知道我試圖解決的問題是什麼;-)

+1

你可以發佈完整的堆棧跟蹤? – 2012-07-31 23:23:38

+0

應該指出的是,這個消息一定是由於HttpClient中的奇怪編程造成的。之前會有一個SSLException的握手失敗,這是應該拋出的。很明顯,執行繼續執行到SSLSession.getPeerCertificate()調用,該調用是在標題中引發異常的唯一API。 – EJP 2012-08-01 22:01:35

回答

24

如果服務器的證書是自簽名的,那麼這是按照設計工作的,您將不得不將服務器的證書導入到密鑰庫中。

假設服務器證書由知名CA簽署,這是因爲現代瀏覽器可用的一組CA證書遠遠大於JDK/JRE附帶的限制集。

您提到的其中一篇文章中給出的EasySSL解決方案只是掩蓋錯誤,並且您不知道服務器是否具有有效證書。

您必須將適當的根CA導入到密鑰庫才能驗證證書。有一個原因,你無法通過股票SSL代碼解決這個問題,這是爲了防止你編寫那些表現得好像安全但不安全的程序。

+0

大多數情況下,SSL服務器將發送鏈但不包括根證書。所以大多數情況下,您不必將整個鏈接導入密鑰存儲庫。但是,您應該明確信任根證書。 – 2012-07-31 23:29:23

+0

@owlstead是的,通常你只需要導入根CA;回答編輯。 – 2012-07-31 23:32:22

+0

我將證書(base64版本)導入到'lib \ security \ cacerts'下的密鑰存儲區,但java仍然給出相同的錯誤。當我將它導入到Windows可信證書存儲區時,chrome停止發送錯誤。但是當我用java keytool做它時,它仍然無法連接。 – nurettin 2016-11-22 08:19:10

6

這時候

...同行無法證明自己的身份(例如拋出;無 證書,所使用的特定密碼套件不支持 認證,或沒有對等身份驗證是在SSL 握手期間建立)引發此異常。

可能是這個異常的原因(堆棧跟蹤在哪裏)會告訴你爲什麼拋出這個異常。很有可能Java附帶的默認密鑰庫不包含(並信任)正在使用的TTP的根證書。

答案是檢索根證書(例如從您的瀏覽器SSL連接),將其導入cacerts文件並使用由Java JDK提供的keytool信任它。否則,您將不得不以編程方式分配另一個信任庫。

0

我不是一個Java開發人員,但使用Java應用程序來測試RESTful API。爲了讓我解決這個錯誤,我不得不在網絡服務器上安裝中間證書,以使錯誤消失。我正在使用lighttpd,原始證書已安裝在IIS服務器上。希望能幫助到你。這些是我在服務器上丟失的證書。

  • CA.crt
  • UTNAddTrustServer_CA.crt
  • AddTrustExternalCARoot.crt
0
keytool -import -v -alias cacerts -keystore cacerts.jks -storepass changeit -file C:\cacerts.cer