2012-09-13 73 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