首页 文章

Java客户端证书和密钥库

提问于
浏览
2

我们正在尝试构建一个MUTUAL / 2WAY认证机制 .

因为我们点击了两个不同的主机,所以我们将相同的客户端证书存储在两个不同别名下的客户端密钥库容器中(请注意相同的指纹):

root@perf-golem-4:/opt/golem# keytool -list -keystore ./client.keystore -storepass ________

Keystore type: JKS
Keystore provider: SUN

Your keystore contains 2 entries

i.domain.io, Jun 16, 2015, trustedCertEntry,
Certificate fingerprint (SHA1): 28:94:45:A1:78:C0:BD:D6:82:7E:09:66:15:11:8D:A5:56:0B:99:39
r.domain.io, Jun 16, 2015, trustedCertEntry,
Certificate fingerprint (SHA1): 28:94:45:A1:78:C0:BD:D6:82:7E:09:66:15:11:8D:A5:56:0B:99:39

现在,在受信任的容器下,我们有目标域证书(请注意它们之间的指纹是如何不同的,并且还与上面的密钥库进行比较):

root@perf-golem-4:/opt/golem# keytool -list -keystore ./trusted.keystore -storepass _______

Keystore type: JKS
Keystore provider: SUN

Your keystore contains 2 entries

i.domain.io, Jun 16, 2015, trustedCertEntry,
Certificate fingerprint (SHA1): 73:F5:96:68:89:56:5E:50:9C:06:69:67:AC:8E:18:D2:D9:C1:33:71
r.domain.io, Jun 16, 2015, trustedCertEntry,
Certificate fingerprint (SHA1): 12:93:C8:41:3F:68:22:8F:40:F8:3C:B9:B6:C4:90:C0:60:49:D0:50

我的理解是,如果你必须存储一个带有与目标域名匹配的别名的证书(在我们的例子中是i.domain.io或r.domain.io),那么当你尝试时,java可以提供相关的证书作为客户端证书与该域的SSL连接,例如https://r.domain.io

我们正在启动我们的应用程序:

java    -Djavax.net.debug=all \
        -Djavax.net.ssl.keyStore=/opt/golem/client.keystore \
        -Djavax.net.ssl.keyStorePassword=_____ \
        -Djavax.net.ssl.trustStore=/opt/golem/trusted.keystore \
        -Djavax.net.ssl.trustStorePassword=_____ \

我们的问题是没有提供客户端证书,也没有从客户端使用,因此,最大的问题是java是否提供与目标域名(或目标SSL证书中的主题行)匹配的别名相关联的客户端证书应该从代码中修改证书的名称?

1 回答

  • 2

    我的理解是,如果你必须存储一个带有与目标域名匹配的别名的证书(在我们的例子中是i.domain.io或r.domain.io),那么java可以提供相关的证书作为客户端证书尝试与该域的SSL连接,例如https://r.domain.io

    事实并非如此 .

    匹配基于certificate_authorities list sent by the server in its TLS CertificateRequest message(发行人)和密钥类型(例如RSA或DSA) . 如果属性不尽如人意,可以选择一些不完美的匹配(参见this answer),但是你愿意接受,除非你明确地改变那里的配置 .

    如果需要中间证书,则'll certainly want to make sure you' ve imported the full chain .

    从本质上讲,在密钥库中存在两倍相同的证书是没有意义的 .

    (您可以尝试通过扩展自己的 X509KeyManager 来强制使用特定的别名,但是's not sufficient; in particular, that'不会使服务器请求它,也不会使链有效 . )

    您需要确保将服务器配置为请求证书 . 这有时可以通过重新协商来完成,因此使用Wireshark可能不一定可以看到 CertificateRequest TLS消息 . 但是,您应该能够使用 -Djavax.net.debug=ssl (或 all )从客户端查看它:如果您在页面上搜索 CertificateRequest ,则official documentation for Debugging SSL/TLS Connections会有一个示例 .

    然后,您需要确保您的证书(或客户端上链的顶部,如果有中间证书)由在该 CertificateRequest 消息中公布的其中一个CA(颁发者DN必须匹配)发出 .

    (如果 CertificateRequest 中的证书颁发机构列表为空,但仍然发送了 CertificateRequest 消息,则客户端将默认发送它在密钥库中找到的第一个证书 . 这种情况是非典型的,因为它需要在服务器端进行自定义配置一般来说 . )

相关问题