以下是不起作用的示例:
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
答案 0 :(得分:4)
如果您查看此域的SSLLabs report,您会看到两种可能的证书路径:
由于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实施都验证远程证书。