gpt4 book ai didi

java - 与代理的 HTTPS 连接导致 SSLHandshakeException

转载 作者:搜寻专家 更新时间:2023-10-31 19:55:22 25 4
gpt4 key购买 nike

几天来我一直在为这个问题苦苦挣扎,但似乎找不到有用的答案...

我有一些软件,每次我想将它与代理服务器一起使用时,它都会导致 SSLHandshakeExceptions。我已经能够使用以下代码重现该问题(这比实际应用程序简单得多):

    HttpsURLConnection con = (HttpsURLConnection) new URL("https://www.google.com").openConnection();
try {
con.connect();
} catch(Exception e) {
e.printStackTrace();
}

如果我在连接到 WiFi 热点(不需要代理服务器)的情况下运行此代码,我将获得连接并且一切正常:

java -cp . SampleJavaURLTest

但是,如果我使用代理服务器运行相同的 Java 命令:

java -cp . -DproxySet=true -DproxyHost={myProxyHost} -DproxyPort={myProxyPort} SampleJavaURLTest

我收到此异常(使用代码片段中的 e.printStackTrace() 打印,使行号无关紧要:

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 com.sun.net.ssl.internal.ssl.Alerts.getSSLException(Alerts.java:174)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.fatal(SSLSocketImpl.java:1731)
at com.sun.net.ssl.internal.ssl.Handshaker.fatalSE(Handshaker.java:241)
at com.sun.net.ssl.internal.ssl.Handshaker.fatalSE(Handshaker.java:235)
at com.sun.net.ssl.internal.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1206)
at com.sun.net.ssl.internal.ssl.ClientHandshaker.processMessage(ClientHandshaker.java:136)
at com.sun.net.ssl.internal.ssl.Handshaker.processLoop(Handshaker.java:593)
at com.sun.net.ssl.internal.ssl.Handshaker.process_record(Handshaker.java:529)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:925)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1170)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1197)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1181)
at sun.net.www.protocol.https.HttpsClient.afterConnect(HttpsClient.java:434)
at sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(AbstractDelegateHttpsURLConnection.java:166)
at sun.net.www.protocol.https.HttpsURLConnectionImpl.connect(HttpsURLConnectionImpl.java:133)
at SampleJavaURLTest.main(SampleJavaURLTest.java:116)
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:323)
at sun.security.validator.PKIXValidator.engineValidate(PKIXValidator.java:217)
at sun.security.validator.Validator.validate(Validator.java:218)
at com.sun.net.ssl.internal.ssl.X509TrustManagerImpl.validate(X509TrustManagerImpl.java:126)
at com.sun.net.ssl.internal.ssl.X509TrustManagerImpl.checkServerTrusted(X509TrustManagerImpl.java:209)
at com.sun.net.ssl.internal.ssl.X509TrustManagerImpl.checkServerTrusted(X509TrustManagerImpl.java:249)
at com.sun.net.ssl.internal.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1185)
... 11 more
Caused by: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
at sun.security.provider.certpath.SunCertPathBuilder.engineBuild(SunCertPathBuilder.java:174)
at java.security.cert.CertPathBuilder.build(CertPathBuilder.java:238)
at sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:318)
... 17 more

因此,第一个合乎逻辑的建议是“使用 InstallCert 程序并添加 google 的证书”。但这不是问题,Java 不喜欢通过代理服务器处理证书的方式。

我使用完全相同的 JVM 运行这两个示例,除了命令行中的代理设置外,没有进一步的配置更改。事实上,这两个测试都是在同一个控制台窗口中完成的,两个测试之间只需要几秒钟就可以切换网络……这是一个 java -v 打印输出:

java version "1.6.0_30"
Java(TM) SE Runtime Environment (build 1.6.0_30-b12)
Java HotSpot(TM) Client VM (build 20.5-b03, mixed mode, sharing)

而且,为了 100% 确定,我还使用更新的 JVM 进行了测试:

java version "1.7.0_10"
Java(TM) SE Runtime Environment (build 1.7.0_10-b18)
Java HotSpot(TM) 64-Bit Server VM (build 23.6-b04, mixed mode)

作为解决方法,我使用这种方法禁用了所有证书验证:

http://code.google.com/p/misc-utils/wiki/JavaHttpsUrl

虽然它并没有真正影响到我,而且我可以接受这种解决方法(如果有人使用虚假证书侵入通信则不是那么重要),但我真的很想知道如何正确地让证书正常工作,因为它们应该。我错过了什么?

最佳答案

如果我理解你是对的,那么你的 SSL 连接在没有代理的情况下会成功,如果你禁用证书验证,使用代理也会成功,但如果你启用证书验证,则使用代理会失败。在这种情况下,代理正在篡改 SSL,例如它进行中间人攻击(在某些防火墙中也称为 SSL 拦截或在 squid 中称为 SSL bump)。如果这不是攻击而是此代理的已知功能(例如扫描 SSL 连接中的病毒等),您需要导入代理拦截 CA,因为由于中间人,您不再说话SSL 连接到 Web 服务器,但连接到代理,然后代理与服务器进行 SSL 对话。

关于java - 与代理的 HTTPS 连接导致 SSLHandshakeException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22044261/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com