为什么Java在SSL握手期间不发送客户端证书?
我正在尝试连接到安全的Web服务。
即使我的密钥库和信任库已正确设置,我也遇到了握手故障。
经过几天的挫败,无休止的谷歌搜索并询问周围的所有人,我发现唯一的问题是java选择在握手期间不将客户端证书发送到服务器。
特别:
- 服务器请求了客户端证书(CN = RootCA)-即“给我一个由根CA签名的证书”
- Java查看密钥库,只发现我的客户端证书由“ SubCA”签名,该证书又由“ RootCA”颁发。进入信任库并没有打扰…嗯,我猜
- 可悲的是,当我尝试将“ SubCA”证书添加到密钥库中时,那根本没有帮助。我确实检查了证书是否已加载到密钥库中。它们可以,但是KeyManager会忽略除客户端证书以外的所有证书。
- 以上所有原因导致java决定它没有满足服务器请求的任何证书,并且不发送任何内容… tadaaa握手失败:-(
我的问题:
- 是否有可能以“破坏证书链”之类的方式将“ SubCA”证书添加到密钥库中,以便KeyManager仅加载客户端证书而忽略其余证书?(Chrome和openssl设法弄清楚了,所以java为什么不能这样做?-请注意,“ SubCA”证书始终作为受信任的机构单独显示,因此Chrome显然在握手期间将其与客户端证书一起正确打包了)
- 这是服务器端的正式“配置问题”吗?该服务器是第三方。我希望服务器请求由“ SubCA”授权机构签名的证书,因为那是他们提供给我们的。我怀疑这在Chrome和openssl中有效的事实是因为它们的“限制较少”,而Java只是“靠书”而失败。
我确实设法解决了这个问题,但是对此我不是很高兴,所以如果有人可以为我澄清这个问题,我将感到非常高兴。
回答:
你可能已将中间CA证书导入了密钥库,而没有将其与拥有客户端证书及其私钥的条目相关联。你应该可以使用查看此内容keytool -v -list -keystore store.jks
。如果每个别名条目仅获得一个证书,那么它们就不会在一起。
你需要将证书及其证书链一起导入具有私钥的密钥库别名中。
要找出哪个密钥库别名具有私钥,请使用keytool -list -keystore store.jks
(我在这里假设JKS存储类型)。这将告诉你以下信息:
Your keystore contains 1 entrymyalias, Feb 15, 2012, PrivateKeyEntry,
Certificate fingerprint (MD5): xxxxxxxx
在这里,别名为myalias
。如果还使用-v
,则应该看到Alias Name: myalias
。
如果尚未单独购买,请从密钥库导出客户端证书:
keytool -exportcert -rfc -file clientcert.pem -keystore store.jks -alias myalias
这应该给你一个PEM文件。
使用文本编辑器(或cat
),准备bundle.pem
包含该客户端证书和中间CA证书(如果需要,还可以包括根CA证书本身)的文件(叫它),以使客户端证书位于开始位置并为其发行者证书就在下面。
看起来应该像这样:
-----BEGIN CERTIFICATE-----MIICajCCAdOgAwIBAgIBAjANBgkqhkiG9w0BAQUFADA7MQswCQYDVQQGEwJVSzEa
....
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIICkjCCAfugAwIBAgIJAKm5bDEMxZd7MA0GCSqGSIb3DQEBBQUAMDsxCzAJBgNV
....
-----END CERTIFICATE-----
现在,将此捆绑包重新导入到你的私钥为的别名中:
keytool -importcert -keystore store.jks -alias myalias -file bundle.pem
以上是 为什么Java在SSL握手期间不发送客户端证书? 的全部内容, 来源链接: utcz.com/qa/416804.html