为什么我会出现握手失败(Java SSL)

我正在通过HTTPS连接到Web服务。 我已经完成了我认为使其工作所需的所有内容,但最终我得到了握手失败。

我发现作为一个新用户,我不能发布超过2个链接,因为“垃圾邮件保护” – 比很多堆栈溢出…无论如何这里是一个链接到一个所有链接拼写的pastebinpost…所以当我在这里写了“链接#1”,它是对这些链接的引用: http : //pastebin.com/y4zGNRC7

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

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

我试过谷歌搜索问题,我在stackoverflow上看到了很多类似的post,但没有任何帮助。 我尝试更改协议版本(“TLSv1”,“SSLv3”,甚至是奇怪的v2 Hello)。 任何帮助将不胜感激 – 也许我可能忽略了一些基本的东西…我在这里绝望… Thanx

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

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

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

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

我为此创建了一个单独的问题…叹息:-( 为什么java握手期间java不发送客户端证书?

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

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

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

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