Java HTTPS客户端证书认证

2024-04-27

我对HTTPS/SSL/TLS我对客户在使用证书进行身份验证时到底应该提供什么内容感到有点困惑。

我正在编写一个 Java 客户端,需要执行一个简单的操作POST数据到特定的URL。这部分工作正常,唯一的问题是它应该重新完成HTTPS. The HTTPS部分相当容易处理(无论是HTTPclient或者使用Java的内置HTTPS支持),但我坚持使用客户端证书进行身份验证。我注意到这里已经有一个非常类似的问题,我还没有用我的代码尝试过(很快就会这样做)。我当前的问题是 - 无论我做什么 - Java 客户端都不会发送证书(我可以用PCAP dumps).

我想知道在使用证书进行身份验证时客户端到底应该向服务器提供什么(特别是对于 Java - 如果这很重要的话)?这是一个JKS文件,或PKCS#12?它们里面应该有什么;只是客户端证书,还是密钥?如果是的话,哪个键?对于所有不同类型的文件、证书类型等存在相当多的混乱。

正如我之前所说,我是新手HTTPS/SSL/TLS所以我也希望获得一些背景信息(不一定是一篇文章;我会满足于好文章的链接)。


终于解决了所有问题,所以我会回答我自己的问题。这些是我用来解决我的特定问题的设置/文件;

The 客户端的密钥库 is a PKCS#12 格式文件包含

  1. 客户的public证书(在本例中由自签名 CA 签名)
  2. 客户的private key

为了生成它,我使用了 OpenSSLpkcs12命令,例如;

openssl pkcs12 -export -in client.crt -inkey client.key -out client.p12 -name "Whatever"

Tip:确保您获得最新的 OpenSSL,not0.9.8h 版本,因为它似乎存在一个错误,不允许您正确生成 PKCS#12 文件。

当服务器明确请求客户端进行身份验证时,Java 客户端将使用此 PKCS#12 文件向服务器提供客户端证书。请参阅关于 TLS 的维基百科文章 http://en.wikipedia.org/wiki/Transport_Layer_Security#Client-authenticated_TLS_handshake概述客户端证书身份验证协议的实际工作原理(还解释了为什么我们需要客户端的私钥)。

The 客户的信任库是一个直截了当的JKS格式文件包含root or 中级 CA 证书。这些 CA 证书将确定您将被允许与哪些端点进行通信,在这种情况下,它将允许您的客户端连接到提供由信任库的 CA 之一签名的证书的任何服务器。

要生成它,您可以使用标准 Java keytool,例如;

keytool -genkey -dname "cn=CLIENT" -alias truststorekey -keyalg RSA -keystore ./client-truststore.jks -keypass whatever -storepass whatever
keytool -import -keystore ./client-truststore.jks -file myca.crt -alias myca

使用此信任库,您的客户端将尝试与所有提供由 CA 标识的证书的服务器进行完整的 SSL 握手myca.crt.

上述文件仅供客户使用。当您还想设置服务器时,该服务器需要自己的密钥和信任库文件。可以在以下位置找到为 Java 客户端和服务器(使用 Tomcat)设置完整工作示例的精彩演练:这个网站 http://emo.sourceforge.net/cert-login-howto.html.

问题/备注/提示

  1. 客户端证书认证只能由服务器强制执行。
  2. (重要的!) 当服务器请求客户端证书(作为 TLS 握手的一部分)时,它还将提供受信任的 CA 列表作为证书请求的一部分。当您希望出示用于身份验证的客户端证书是not由这些 CA 之一签署,它根本不会被呈现(在我看来,这是奇怪的行为,但我确信这是有原因的)。这是我出现问题的主要原因,因为对方没有正确配置他们的服务器来接受我的自签名客户端证书,并且我们认为问题出在我身上,因为我没有在请求中正确提供客户端证书。
  3. 获取 Wireshark。它具有出色的 SSL/HTTPS 数据包分析功能,对于调试和查找问题将提供巨大帮助。它类似于-Djavax.net.debug=ssl但如果您对 Java SSL 调试输出感到不舒服,它会更结构化并且(可以说)更容易解释。
  4. 完全可以使用 Apache httpclient 库。如果您想使用 httpclient,只需将目标 URL 替换为 HTTPS 等效项,并添加以下 JVM 参数(对于任何其他客户端来说都是相同的,无论您想使用哪个库通过 HTTP/HTTPS 发送/接收数据) :

    -Djavax.net.debug=ssl
    -Djavax.net.ssl.keyStoreType=pkcs12
    -Djavax.net.ssl.keyStore=client.p12
    -Djavax.net.ssl.keyStorePassword=whatever
    -Djavax.net.ssl.trustStoreType=jks
    -Djavax.net.ssl.trustStore=client-truststore.jks
    -Djavax.net.ssl.trustStorePassword=whatever
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Java HTTPS客户端证书认证 的相关文章

随机推荐