Java Https客户端证书的工作方式与浏览器或其他工具完全不同

use*_*144 5 java ssl https certificate

似乎我们无法配置我们的Java客户端来正确处理SSL连接.

我们可以使用具有指定客户端证书和curl工具的浏览器成功连接到HTTPS URL,但不能使用我们的java客户端或基于java的SOAP UI工具.即使我们在浏览器中使用相同的*.p12证书(工作正常)并在SOAP UI工具中(不起作用).

所以,我们有以下信息:

  1. 公共客户证书(pem格式)
  2. 客户端的私钥(pem格式)
  3. 服务器用于验证客户端证书的CA.

我们将这些pem证书转换为jks和p12,并使用apache http client进行连接.并且正如提到的那样,相同的证书适用于浏览器,但对于自定义客户端或基于Java的Java UI都不起作用.

首先,我猜测我们在那里描述了以下问题:
当服务器请求客户端证书(作为TLS握手的一部分)时,它还将提供可信CA的列表作为证书请求的一部分.如果您希望提供用于身份验证的客户端证书未由其中一个CA签名,则根本不会显示该证书

但似乎我们有这样的问题它不会解析浏览器的这个证书.因为默认情况下浏览器默认不允许使用不正确的(具有不同的颁发者)证书.

我根据以下教程创建的客户端:

所以,基本上我有问题:

  1. 如何知道客户端证书是否全部发送:我们使用org.apache.http.conn.ssl.SSLSocketFactory可能在什么地方进行调试;
  2. 问题可能是什么,可能是描述浏览器SSL配置和基于java的工具(可能更严格地说是java SSL验证)的差异的任何好的参考?

更新1

我们尝试使用openssl s_client工具.输出显示服务器证书符合我们的预期,但客户端证书验证没有CA:未

发送客户端证书CA名称

openssl s_client的语法,如果使用连接到443而没有指定模式(https://).所以我们决定在没有架构的情况下在浏览器中尝试我们的URL但使用443端口.服务器响应:

普通HTTP请求已发送到HTTPS端口

接下来我们在这次调查中的步骤是尝试wireshark.首先我们使用浏览器进行了正确的会话,然后我们尝试了我们的应用 我们也试过openssl s_client.

区别在于服务器密钥交换数据包.虽然浏览器数据包有一个证书请求,但openssl和我们的应用程序在该数据包中没有这样的字段.此外,如果浏览器不发送任何证书,则该字段仍然存在于数据包中.

因此,只有浏览器获得证书请求.任何关于为什么会发生这种情况的想法都值得赞赏

评论中的问题答案

  • 我们正在使用java 1.7
  • 它是初始客户端证书身份验证
  • 当我们使用时, openssl s_client -connect your.server.name:443 我们返回有效的服务器证书并且没有发送客户端证书CA名称.我们还得到验证错误:num = 2:无法获得颁发者证书.
  • 我们从s_client和浏览器获得的服务器证书是相同的
  • 没有公布的CA证书列表没有发送客户端证书CA名称

更新2

经过一些调查和研究,我们设法找出问题的根本原因.所以我们在服务器上启用了SNI(服务器名称指示),我们的应用程序正在使用apache httpclient 4.2.1.此版本的客户端不支持SNI扩展,也不在Client Hello数据包中发送server_name扩展.之后该服务器不通告客户端使用客户端证书进行身份验证.此问题已在4.3.2版本中修复.

现在我们正在尝试检查4.3.2版本的httpclient是否正确发送server_name扩展.