java - createSocket、connect 和 connectionTimeout 的 HTTPS 问题

标签 java ssl https

当我像这样创建 SSL 套接字时:

sslSocket = (SSLSocket) socketFactory.createSocket(host, port);

一切正常。 socketFactory 是一个 SSLSocketFactory.getDefault()。但是,我想设置连接超时。因此,我将上面的代码更改为以下代码:

sslSocket = (SSLSocket) socketFactory.createSocket();
sslSocket.connect(new InetSocketAddress(host, port), connectionTimeout);

但后来我得到了以下异常:

Exception in thread "main" jodd.http.HttpException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target;

导致异常:

sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target

当我对此进行调试时,我注意到在第一种情况下,代码从请求的站点获取所有有效证书。在第二种情况下,这些证书丢失,因此出现错误。

我还需要在我的 2-liner 更改中添加什么,才能使其像第一个 one-liner 版本一样工作?

完整的堆栈跟踪

jodd.http.HttpException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target; <--- sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
    at jodd.http.HttpRequest.open(HttpRequest.java:667)
    at jodd.http.HttpRequest.open(HttpRequest.java:649)
    at jodd.http.HttpRequest._send(HttpRequest.java:747)
    at jodd.http.HttpRequest.send(HttpRequest.java:742)
    at jodd.JoddHttpTest.main(JoddHttpTest.java:56)
Caused by: 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:1949)
    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:1509)
    at sun.security.ssl.ClientHandshaker.processMessage(ClientHandshaker.java:216)
    at sun.security.ssl.Handshaker.processLoop(Handshaker.java:979)
    at sun.security.ssl.Handshaker.process_record(Handshaker.java:914)
    at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:1062)
    at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1375)
    at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1403)
    at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1387)
    at jodd.http.net.SocketHttpConnectionProvider.createSSLSocket(SocketHttpConnectionProvider.java:153)
    at jodd.http.net.SocketHttpConnectionProvider.createHttpConnection(SocketHttpConnectionProvider.java:68)
    at jodd.http.HttpRequest.open(HttpRequest.java:665)
    ... 4 more
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:1491)
    ... 14 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:141)
    at sun.security.provider.certpath.SunCertPathBuilder.engineBuild(SunCertPathBuilder.java:126)
    at java.security.cert.CertPathBuilder.build(CertPathBuilder.java:280)
    at sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:382)
    ... 20 more
---[cause]------------------------------------------------------------------------
sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
    at sun.security.provider.certpath.SunCertPathBuilder.build(SunCertPathBuilder.java:141)
    at sun.security.provider.certpath.SunCertPathBuilder.engineBuild(SunCertPathBuilder.java:126)
    at java.security.cert.CertPathBuilder.build(CertPathBuilder.java:280)
    at sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:382)
    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:1491)
    at sun.security.ssl.ClientHandshaker.processMessage(ClientHandshaker.java:216)
    at sun.security.ssl.Handshaker.processLoop(Handshaker.java:979)
    at sun.security.ssl.Handshaker.process_record(Handshaker.java:914)
    at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:1062)
    at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1375)
    at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1403)
    at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1387)
    at jodd.http.net.SocketHttpConnectionProvider.createSSLSocket(SocketHttpConnectionProvider.java:153)
    at jodd.http.net.SocketHttpConnectionProvider.createHttpConnection(SocketHttpConnectionProvider.java:68)
    at jodd.http.HttpRequest.open(HttpRequest.java:665)
    at jodd.http.HttpRequest.open(HttpRequest.java:649)
    at jodd.http.HttpRequest._send(HttpRequest.java:747)
    at jodd.http.HttpRequest.send(HttpRequest.java:742)
    at jodd.JoddHttpTest.main(JoddHttpTest.java:56)

最佳答案

答案在这里。根据我的经验,这是:

sslSocket = (SSLSocket) socketFactory.createSocket();
sslSocket.connect(new InetSocketAddress(host, port), connectionTimeout);

不起作用(尽管你到处都能看到这个解决方案!)。相反,我执行了以下操作:创建一个常规套接字,然后将其包装为 SSL 套接字:

Socket sock = new Socket();
sock.connect(new InetSocketAddress(host, port), connectionTimeout);
sslSocket = (SSLSocket)socketFactory.createSocket(sock, host, port, true);

其中 socketFactory 是一个 SSLSocketFactory 实例。

关于java - createSocket、connect 和 connectionTimeout 的 HTTPS 问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38740399/

相关文章:

java - 如何对 Double 而不是 Integer 进行 Java lambda 求和?

python - Django | unicorn |导入错误 : No module named _ssl

c++ - 如果 ssl::stream<tcp::socket> 有未决操作,我是否不允许删除它?

java - 如何使用 JSOUP 绕过 cloudflare ddos​​ 或 5 秒后重定向?

ruby-on-rails - 在 Rails 中为 http 请求强制使用 SSL

java - Netbeans 错误 : Could not find or load main class (again)

java - 在 JavaFX Webview 中运行 URLConnection uc

java - 如何根据名称对数组列表进行排序,并且数组列表包含带有人名首字母的名称?

asp.net - 优雅地检测用户无法支持来自 ASP.net 的 SHA256 SSL 连接

scala - 如何在不使我的整个应用程序不安全的情况下忽略 Play Framework WS SSL 证书?