2012-09-13 44 views
1

我的Java程序使用GitHub的原始地址訪問版本文件以獲取最新版本。這個地址的格式爲https://raw.github.com/user/repository/branch/version_file使用未經驗證的SSL證書通過HTTPS下載文件

在測試階段,我用這個用下面的代碼沒有問題:

currentVersion = new Version(plugin.getDescription().getVersion()); 

URL url = new URL("https://raw.github.com/zonedabone/CommandSigns/master/VERSION"); 
URLConnection connection = url.openConnection(); 
BufferedReader in = new BufferedReader(new InputStreamReader(connection.getInputStream())); 
newestVersion = new Version(in.readLine()); 

if (currentVersion.compareTo(newestVersion) < 0) 
    newAvailable = true; 

然而,一些用戶抱怨以下錯誤:

sun.security.validator.ValidatorException: 
    PKIX path building failed: 
    sun.security.provider.certpath.SunCertPathBuilderException: 
     unable to find valid certification path to requested target 

Java正在抱怨它無法驗證SSL證書。 GitHub的證書由DigiCert驗證,但顯然一些Java版本不會識別這一點。

我讀過有兩種方法可以解決這個問題:將證書添加到TrustStore並完全禁用驗證。

答案建議在計算器上或者使用的允許,所有信任庫,這將是考慮到它是不是一個「測試環境」,或者如果他們展示如何添加證書,他們通常的範圍內一個非常糟糕的主意鏈接到一個破碎的網頁。

有人可以提供新的信息嗎?

+0

此問題已在SO和網上進行了無數次的提問和回答。請在「java自簽名證書」上進行Google搜索並刪除此問題。 –

+0

[我如何使用Java HttpsURLConnection接受自簽名證書?](http://stackoverflow.com/questions/859111/how-do-i-accept-a-self-signed-certificate-with -a-java-httpsurlconnection) –

+0

@JimGarrison,真的,不幸的是,谷歌搜索將導致一些答案,建議使用信任管理器,信任任何證書... – Bruno

回答

4

一是理論......正如JSSE Reference Guide說:

IMPORTANT NOTE: The JDK ships with a limited number of trusted root certificates in the /lib/security/cacerts file. As documented in keytool, it is your responsibility to maintain (that is, add/remove) the certificates contained in this file if you use this file as a truststore.

Depending on the certificate configuration of the servers you contact, you may need to add additional root certificate(s). Obtain the needed specific root certificate(s) from the appropriate vendor.

用戶應保持CA的列表證書本身。不幸的是,一些人不知道該怎麼做。他們可以使用另一個JRE的cacerts文件(更新)到他們自己的安裝中。

您可以使用信任管理器來信任任何證書並專門用於該連接,但這不是一個好主意,因爲它打開了與潛在的MITM攻擊的連接。這個不安全的解決方案有足夠的代碼示例。

如果您要信任特定證書,最佳解決方案是使用特定信任庫正確加載它,如this answer中所述。如果要將其與應用程序捆綁在一起,您甚至可以從類加載器的InputStream中加載該信任庫。

或者,如果可能,您可以直接使用操作系統信任庫。在Windows上,您可以按照this article中所述加載Windows-ROOT密鑰庫。在OSX上,您可以加載KeychainStore

+0

您建議的第一個解決方案似乎非常合理。我現在已經休息了一個星期,所以在接受之前我不得不讓其他插件開發人員看看這個。第二個答案是不可能的,因爲該插件不依賴於操作系統。 – CJxD

-2

您可以實現一個HttpsURLConnection的以 「所有」 -TrustManager

http://bitsandcodes.blogspot.de/2010/08/create-trust-manager-that-trust-all-ssl.html

+0

有沒有更好的例子?這個使用了不推薦的類型,比如SSLContext,並且使用JSSESocketFactory,它不能在我的IDE中解析。 – CJxD

+0

編輯:類型不被棄用,我只是做錯了進口。但是,我仍然不能使用JSSESocketFactory,因爲我沒有使用org.apache。 – CJxD

+0

'JSSESocketFactory'是Axis專用的,它與問題無關。另外,盲目信任所有證書是一個壞主意。 – Bruno