【发布时间】:2017-07-13 06:42:23
【问题描述】:
我正在尝试使用 HtmlUnit 登录使用 HTTPS 连接的网站,但我收到了由语句引起的错误
page = webClient.getPage(url);
例外是
error: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`
到目前为止我做了什么:
-
使用 Firefox 导出网站证书链中的各个证书,并使用 java keytool 将它们导入到 JVM 的默认密钥库中,例如:
keytool -import -trustcacerts -alias root -file C:\Users\myUser\Desktop\Certificates\VeriSignClass3PublicPrimaryCertificationAuthority-G5.crt -keystore C:\Program Files (x86)\Java\jre1.8.0_91\lib\security\cacerts 使用 java keytool 启动了一个新的密钥库,并且只导入了相关的根证书、中间证书和特定网站的证书。
-
使用
将此证书设置为 java 证书存储System.setProperty("javax.net.ssl.trustStore", "C:/Users/Henry/workspace/AutoEtime/cacerts"); - 尝试将浏览器版本更改为 Chrome,然后更改为 Firefox
- 尝试使用来自 confluence.atlassian.com 的 SSLPoke.class 来测试证书是否正确,但是我不知道要连接的端口,并且使用默认的 433 会给出
ConnectException: Connection timed out
我没有尝试过使用here 中的WebClientOptions 文档中列出的任何其他方法,因为我不确定如何使用它们来获得我想要的效果。
我在网上看到的最常见的答案之一是建议使用webClient.setUseInsecureSSL(true);
这可以很好地测试我的应用程序,但是我需要使用 SSL 保护连接,因为我用于连接到网站的用户名和密码很敏感。
我想补充的一件有趣的事情是,每 5-10 次尝试中就有一个确实有效,并且不会抛出 SSLHandshakeException,即使我没有对代码进行任何更改。
我该如何解决这个问题?另外,为什么它每隔一段时间就会起作用?
【问题讨论】:
-
HTTPS 的默认端口是 443 而不是 433。在 Windows 上以
\Program Files或\Program Files (x86)手动更改/写入文件是个坏主意;对于较新的 Windows 版本,此类更改可能不起作用或仅有时起作用,这可能解释了您的间歇性行为。要么在别处安装 Java(我喜欢c:\Java),要么使用第二个项目符号:创建自己的密钥库并指向它;如果服务器行为正确,您应该只需要根证书,并确保在 JVM 进程中第一次使用 SSL 之前设置trustStore(如果不是trustStorePassword,则设置changeit)。 -
您是否可以提供您尝试使用的主机名?
-
你是对的,戴夫,我在我的问题和运行 SSLPoke.class 时都输入了错误的端口。我一更改并添加了证书,它就成功连接了。
标签: java ssl https htmlunit sslhandshakeexception