为什么java握手期间java不发送客户端证书?

Jak*_*atý 63 java ssl https certificate ca

我正在尝试连接到安全的Web服务.

即使我的密钥库和信任库已正确设置,我也会收到握手失败.

经过几天的挫折,无休止的谷歌搜索并询问周围的每个人我发现唯一的问题是java选择不在握手期间将客户端证书发送到服务器.

特别:

  1. 服务器请求客户端证书(CN = RootCA) - 即"给我一个由根CA签名的证书"
  2. Java查看了密钥库,只发现了我的客户端证书,该证书由"SubCA"签署,而"SubCA"又由"RootCA"签发.它没有费心去查看信任库...呃好吧我猜
  3. 可悲的是,当我试图将"SubCA"证书添加到密钥库时,这根本没有帮助.我确实检查了证书是否被加载到密钥库中.他们这样做,但KeyManager忽略除客户端之外的所有证书.
  4. 所有上述情况导致java决定它没有任何满足服务器请求的证书并且什么都不发送... tadaaa握手失败:-(

我的问题:

  1. 我是否有可能以"破坏证书链"或某种方式将"SubCA"证书添加到密钥库中,以便KeyManager仅加载客户端证书并忽略其余证书?(Chrome和openssl设法解决这个问题,为什么不能使用java? - 请注意,"SubCA"证书总是作为受信任的权限单独提供,因此Chrome显然在握手期间正确地将其与客户端证书一起打包)
  2. 这是服务器端的正式"配置问题"吗?服务器是第三方.我希望服务器能够请求由"SubCA"授权机构签署的证书,因为这是他们为我们提供的.我怀疑这个在Chrome和openssl中工作的事实是因为它们"限制性较小"而java只是"按书"而且失败了.

我确实为此设置了一个肮脏的解决方法,但我对此并不高兴所以如果有人能为我澄清这个,我会很高兴.

Bru*_*uno 93

您可能已将中间CA证书导入密钥库,而无需将其与具有客户端证书及其私钥的条目相关联.你应该能够看到这个keytool -v -list -keystore store.jks.如果每个别名条目只获得一个证书,则它们不在一起.

您需要将证书及其链一起导入具有私钥的密钥库别名.

要找出哪个密钥库别名具有私钥,请使用keytool -list -keystore store.jks(我在这里假设JKS商店类型).这会告诉你这样的事情:

Your keystore contains 1 entry

myalias, Feb 15, 2012, PrivateKeyEntry, 
Certificate fingerprint (MD5): xxxxxxxx
Run Code Online (Sandbox Code Playgroud)

别名是myalias.如果您使用-v此外,您应该看到Alias Name: myalias.

如果您尚未单独使用它,请从密钥库导出客户端证书:

keytool -exportcert -rfc -file clientcert.pem -keystore store.jks -alias myalias
Run Code Online (Sandbox Code Playgroud)

这应该给你一个PEM文件.

使用文本编辑器(或cat),bundle.pem使用该客户端证书和中间CA证书(如果需要,可能还有根CA证书本身)准备文件(让我们称之为),以便客户端证书位于开头及其颁发者证书就在.

这应该是这样的:

-----BEGIN CERTIFICATE-----
MIICajCCAdOgAwIBAgIBAjANBgkqhkiG9w0BAQUFADA7MQswCQYDVQQGEwJVSzEa
....
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIICkjCCAfugAwIBAgIJAKm5bDEMxZd7MA0GCSqGSIb3DQEBBQUAMDsxCzAJBgNV
....
-----END CERTIFICATE-----
Run Code Online (Sandbox Code Playgroud)

现在,将此捆绑包重新导入到私钥所在的别名中:

keytool -importcert -keystore store.jks -alias myalias -file bundle.pem
Run Code Online (Sandbox Code Playgroud)

  • 感谢一百万布鲁诺-做到了。我认为这可能会有更多记录。我只是花了几天的时间来弄清楚到底是怎么回事。Java的提示实际上是不存在的。 (5认同)
  • 我也需要将证书和私钥组合到导入中,但我开始使用*.pem证书文件(以"----- BEGIN CERTIFICATE -----"开头)和*.key私有键("----- BEGIN RSA私钥-----").我尝试连接它们然后导入,但我得到:keytool错误:java.lang.Exception:输入不是X.509证书.我出错的任何想法?我在http://stackoverflow.com/questions/5297867/ssl-tomcat-certificate-error/11984173#11984173上阅读了可能需要转换为密钥类型pkcs12的内容.有任何想法吗?我被卡住了!谢谢. (2认同)

小智 5

作为此处的添加,您可以使用%> openssl s_client -connect host.example.com:443并查看转储并检查所有主证书是否对客户端有效.您正在输出的底部寻找此信息. 验证返回码:0(ok)

如果添加-showcerts,它将转储与主机证书一起发送的钥匙串的所有信息,这是您加载到钥匙串中的信息.