【问题标题】:Why do I get a handshake failure (Java SSL)为什么我会遇到握手失败(Java SSL)
【发布时间】:2012-03-04 04:25:14
【问题描述】:

我正在通过 HTTPS 连接到 Web 服务。我已经完成了我认为让它工作所需的一切,但最后我握手失败了。

我发现作为一个新用户,由于“垃圾邮件保护”,我不能发布超过 2 个链接 - 非常感谢 stackoverflow ......无论如何,这里有一个 pastebin 帖子的链接,其中所有链接都拼写出来...... .so 当我在这里写“link#1”时,它是对这些链接的引用:http://pastebin.com/y4zGNRC7

  • 我使用 HttpClient(服务 URL 上的 GET)验证了相同的行为,并通过 CXF 代理实际调用了 Web 服务
  • 我正在设置密钥库和信任库 - 我尝试了“in code”方式(link#1)和设置系统属性 - 即 System.setProperty("javax.net.ssl.keyStore", "mykeystore .jks");
  • SSL 调试已开启 (javax.net.debug=all)
  • SSL 调试会脱口而出 keystore 和 truststore 的内容(即看起来像 java“知道它们”)-link#2
  • 似乎有一些客户端-服务器通信正在进行,但随后由于某种原因链接#3 崩溃
  • 我在浏览器 (Chrome) 和 openssl s_client 中使用客户端和 CA 证书成功连接到服务器
  • wireshark 显示来自 java (link#4) 的客户端-服务器对话较少,例如来自 Chrome (link#5)

另一个奇怪的事情是,当我设置密钥库和不设置密钥库时,我似乎得到了相同的行为(唯一的区别是,当我执行密钥库时,内容会打印在控制台中,但是就是这样)。

我尝试用谷歌搜索这个问题,我在 stackoverflow 上看到了许多类似的帖子,但没有任何帮助。 我尝试更改协议版本(“TLSv1”、“SSLv3”,甚至是奇怪的 v2 Hello)。 任何帮助将不胜感激 - 也许我可能忽略了一些基本的事情......我在这里变得绝望...... 谢谢

PS 我在 Fedora Core 15(64 位)上运行 java 1.6 update 30

【问题讨论】:

  • 你能发布异常堆栈跟踪吗?
  • “我发现作为一个新用户,由于“垃圾邮件保护”,我不能发布超过 2 个链接 - 非常感谢 stackoverflow”。如果你经常使用这个网站,你会意识到 SO 的垃圾邮件保护措施是一件好事。
  • 关于链接的主题,发布 pastebin 链接和类似的链接被认为是不好的形式,因为它们很快就会消失,使未来的读者无法理解问题。
  • 这里是堆栈跟踪pastebin.com/dbXPYRmS
  • 是的,对不起,我有点激动,但我了解它如何帮助防止垃圾邮件......外部链接是 imo 一种很好的方式,可以用太多细节“不污染”问题......加上没有字数限制吗? Pastebin 允许您选择帖子的“过期”...而“从不”似乎是一个不错的选择 ;-) 如果 stackoverflow 本身提供这样的功能会很好。

标签: java exception ssl cxf handshake


【解决方案1】:

您没有提供足够的信息,但我猜您的 client 信任库配置不正确。信任库包含用于签署其他证书的受信任证书,并且必须包括服务器和客户端证书链的根证书。客户端密钥库包含客户端 SSL 证书和私钥。

【讨论】:

  • 感谢您的回复 Greg。请告诉我应该提供哪些更多信息。我试图尽可能彻底,但我知道我可能错过了一些东西。正如我写的那样,我设置了 truststorekeystore。我确实将 Xs 放在日志中,而不是实际的证书名称和内容,因为我不想在网上发布这些内容。密钥库包含客户端证书和私钥。信任库包含颁发证书的 CA 的证书和根 CA 证书。堆栈跟踪在这里似乎没有太大帮助(我在上面的评论中发布了它)。
  • 似乎客户端 keystore 已加载,但客户端证书未提供给服务器,这就是握手失败的原因。日志显示一个空的客户端证书链。我不知道为什么:-(
【解决方案2】:

我认为不包含 CA 的信任库是最有可能出现的问题。您可以使用 Java keytool 将站点的证书导入到 cacerts 文件中,执行以下操作:

keytool -keystore pathtocacerts -import -trustcacerts -v -alias aliasName -file root.crt

默认的 cacerts 密钥库密码是 changeitcacerts 文件通常在jre/lib/security 目录下。

【讨论】:

  • 我很确定信任库确实包含 CA。当这不起作用时,我还将根 CA 证书导入到信任库中……但这似乎没有帮助。
  • 请注意,启用 SSL 调试后,信任库和密钥库的内容都会打印在控制台中。客户端证书和 CA 证书(不是根证书)也足以在浏览器中工作。
  • 我尝试使用 keytool 检查商店的内容,一切似乎都正常。我什至尝试在启动时通过命令行选项设置两个商店(即-Djavax.net.ssl.keyStore=),但无济于事......
【解决方案3】:

问题是即使设置了密钥库和信任库,java 还是决定不将客户端证书发送到服务器。原因是服务器请求了一个由 RootCA 机构签署的证书,但客户端证书是由 SubCA 机构(由 RootCA 颁发)签署的。

最初密钥库仅包含客户端证书,信任库包含 SubCA 证书。 然后我也尝试将 SubCA 证书添加到密钥库,但 java 忽略了它。

所以这解决了 hanshake 失败之谜,但不是我的问题。

我为此创建了一个单独的问题...叹息:-( why doesn't java send the client certificate during SSL handshake?

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-09-27
    • 2018-03-31
    • 1970-01-01
    • 1970-01-01
    • 2018-07-28
    • 1970-01-01
    相关资源
    最近更新 更多