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

标签 java ssl https certificate ca

我正在尝试连接到安全的网络服务。

即使我的 keystore 和信任库已正确设置,我也遇到了握手失败。

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

具体来说:

  1. 服务器请求客户端证书 (CN=RootCA) - 即“给我一个由根 CA 签名的证书”
  2. Java 查看了 keystore ,只找到了我的客户端证书,该证书由“SubCA”签名,而该证书又由“RootCA”颁发。它没有费心去查看信任库...嗯,我猜是的
  3. 遗憾的是,当我尝试将“SubCA”证书添加到 keystore 时,这根本没有帮助。我确实检查了证书是否已加载到 keystore 中。确实如此,但 KeyManager 会忽略除客户端之外的所有证书。
  4. 以上所有情况都导致 java 认为它没有任何证书可以满足服务器的请求并且什么也不发送...tadaaa 握手失败:-(

我的问题:

  1. 我是否有可能以“破坏证书链”或其他方式将“SubCA”证书添加到 keystore ,以便 KeyManager 仅加载客户端证书而忽略其余证书? (Chrome 和 openssl 设法弄清楚了,为什么 java 不能呢? - 请注意,“SubCA”证书始终作为受信任的权威单独呈现,因此 Chrome 显然在握手期间正确地将其与客户端证书一起打包)
  2. 这是服务器端的正式“配置问题”吗?服务器是第三方。我希望服务器请求由“SubCA”机构签署的证书,因为这是他们为我们提供的。我怀疑这在 Chrome 和 openssl 中有效的事实是因为它们“限制较少”,而 java 只是“按部就类”并且失败了。

我确实设法为此制定了一个肮脏的解决方法,但我对此不太满意,所以如果有人能为我澄清这一点,我会很高兴。

最佳答案

您可能已将中间 CA 证书导入 keystore ,但未将其与您拥有客户端证书及其私钥的条目相关联。您应该能够使用 keytool -v -list -keystore store.jks 看到这一点。如果每个别名条目仅获得一个证书,则它们不在一起。

您需要将您的证书及其链一起导入到拥有您的私钥的 keystore 别名中。

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

Your keystore contains 1 entry

myalias, Feb 15, 2012, PrivateKeyEntry, 
Certificate fingerprint (MD5): xxxxxxxx

这里的别名是myalias。如果除此之外还使用 -v,您应该会看到 Alias Name: myalias

如果您还没有单独拥有它,请从 keystore 中导出您的客户端证书:

keytool -exportcert -rfc -file clientcert.pem -keystore store.jks -alias myalias

这应该会给你一个 PEM 文件。

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

这应该看起来像:

-----BEGIN CERTIFICATE-----
MIICajCCAdOgAwIBAgIBAjANBgkqhkiG9w0BAQUFADA7MQswCQYDVQQGEwJVSzEa
....
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIICkjCCAfugAwIBAgIJAKm5bDEMxZd7MA0GCSqGSIb3DQEBBQUAMDsxCzAJBgNV
....
-----END CERTIFICATE-----

现在,将此 bundle 重新导入到您的私钥所在的别名中:

keytool -importcert -keystore store.jks -alias myalias -file bundle.pem

关于java - 为什么 java 在 SSL 握手期间不发送客户端证书?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9299133/

相关文章:

java - 使用 Wildfly 对 http 响应进行 Gzip 编码

java - JDBC 连接在 IDE (eclipse) 中有效,但在 .jar 文件中无效

asp.net - 在asp.net本地开发时如何模仿SSL?

javascript - SSL 版本或密码不匹配 ExpressJS

java - ListView 中 CheckedTextView 的监听器

ssl - Arduino ESP8266 + Mega 使用 SSL

apache - 子域在 http 上工作正常,在 https 上不工作

ruby-on-rails - Heroku SSL 证书不包含 cname

ssl - 自定义域丢包

Java 8 分组为对象集合