通过HTTPS下载网站失败

时间:2015-05-27 17:59:00

标签: java ssl https certificate

以下是不起作用的示例:

public class Temp {
  public static void main(String[] args) throws Exception {
    new URL("https://float.software").openConnection().getInputStream();
  }
}

在我的浏览器中转到https://float.software/的工作正常。但是java抛出了这个异常:

Exception in thread "main" javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
    at sun.security.ssl.Alerts.getSSLException(Alerts.java:192)
    at sun.security.ssl.SSLSocketImpl.fatal(SSLSocketImpl.java:1937)
    at sun.security.ssl.Handshaker.fatalSE(Handshaker.java:302)
    at sun.security.ssl.Handshaker.fatalSE(Handshaker.java:296)
    at sun.security.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1478)
    at sun.security.ssl.ClientHandshaker.processMessage(ClientHandshaker.java:212)
    at sun.security.ssl.Handshaker.processLoop(Handshaker.java:957)
    at sun.security.ssl.Handshaker.process_record(Handshaker.java:892)
    at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:1050)
    at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1363)
    at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1391)
    at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1375)
    at sun.net.www.protocol.https.HttpsClient.afterConnect(HttpsClient.java:563)
    at sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(AbstractDelegateHttpsURLConnection.java:185)
    at sun.net.www.protocol.http.HttpURLConnection.getInputStream0(HttpURLConnection.java:1512)
    at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1440)
    at sun.net.www.protocol.https.HttpsURLConnectionImpl.getInputStream(HttpsURLConnectionImpl.java:254)
    at fb.Temp.main(Temp.java:8)
Caused by: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
    at sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:387)
    at sun.security.validator.PKIXValidator.engineValidate(PKIXValidator.java:292)
    at sun.security.validator.Validator.validate(Validator.java:260)
    at sun.security.ssl.X509TrustManagerImpl.validate(X509TrustManagerImpl.java:324)
    at sun.security.ssl.X509TrustManagerImpl.checkTrusted(X509TrustManagerImpl.java:229)
    at sun.security.ssl.X509TrustManagerImpl.checkServerTrusted(X509TrustManagerImpl.java:124)
    at sun.security.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1460)
    ... 13 more
Caused by: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
    at sun.security.provider.certpath.SunCertPathBuilder.build(SunCertPathBuilder.java:145)
    at sun.security.provider.certpath.SunCertPathBuilder.engineBuild(SunCertPathBuilder.java:131)
    at java.security.cert.CertPathBuilder.build(CertPathBuilder.java:280)
    at sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:382)
    ... 19 more

当我查看其他答案时,他们都谈论安装证书。我不认为我应该安装证书。这不是自签名的。它使用真正的证书颁发机构。 Python下载此URL就好了。铬也是如此。 Java没有。

编辑:对于那些说Comodo是尚未添加到Java的新权限的人来说,它是作为Java 5中的根添加的。请参阅http://forums.comodo.com/comodo-cleaning-essentials-killswitch-autoruns-cce/how-do-i-unblock-a-processexecutable-t17086.0.html

2 个答案:

答案 0 :(得分:4)

如果您查看此域的SSLLabs report,您会看到两种可能的证书路径:

  • 第一个(较短的)一端期望客户信任“COMODO RSA证书颁发机构”。尽管此CA自2010年起有效,但最近(大约半年前)才包含在Firefox等浏览器中,请参阅https://bugzilla.mozilla.org/show_bug.cgi?id=1062589。在大多数浏览器之外,您不会发现此CA是受信任的,即在Java附带的信任库或类似文件中(Java不使用系统信任库)。
  • 另一个较长的证书路径需要受信任的根CA“AddTrust External CA Root”。此CA在浏览器和操作系统中包含多年,可能也在Java信任库中。不幸的是,要验证此证书路径,需要一个服务器不提供的附加链证书(在SSLLabs报告中标记为“额外下载”)。

由于Java不包含第一个路径中的Root-CA,因此无法对其进行验证。由于缺少链证书,它无法验证第二条路径。这意味着验证失败。

  

Python下载此网址就好了。铬也是如此。

Chrome有更新的root-CA。 Chrome也试图下载丢失的链证书,而Java,Python等则不会。

Python最近才开始默认验证证书,即自2.7.9+和3.4.3+以来。所有以前的(这意味着大多数安装)版本都没有验证证书(除了使用请求库时),所以它只是工作(典型的问题:没有人注意到这是不安全的,因为它似乎工作)。请参阅https://www.python.org/dev/peps/pep-0476/

答案 1 :(得分:1)

如果您使用的是旧版Java,则可能需要更新cacerts文件。 float.software的SSL证书由" COMODO RSA证书颁发机构"签署,该证书仅自2014年2月起生效。您的Java安装可能比旧版本更早。

另外,请注意Python。并非所有HTTPS实施都验证远程证书。