2

我对双向身份验证有疑问。我使用 tomcat6 作为服务器,作为客户端我尝试 IE、Firefox 和我自己的 java 应用程序。

使用别人给我的 PFX 证书会出现问题。我必须将它们用作客户端证书,所以我只需将其添加到服务器上的受信任证书中,然后在浏览器中的用户证书中使用它。问题是我收到 bad_certificate 警报。

我通过为服务器和客户端生成我自己的证书并在两个密钥库等中添加受信任的公钥,成功地完成了双向 ssl...

当我查看wireshark日志时,我看到该服务器发送了良好的证书请求,但是当我使用自己生成的证书时,客户端发送了空证书(11字节长度的数据包)而不是500多个字节。

可能是什么问题?为什么客户不发送好的证书?:(

4

2 回答 2

3

仔细查看您的客户端证书,特别是 X509v3 扩展“密钥使用”和“扩展密钥使用”。对于客户端身份验证,它们可能被标记为不受信任。

使用openssl 命令行工具

$ openssl pkcs12 -in server-only.pfx -nokeys | openssl x509 -noout -purpose
Enter Import Password:
MAC verified OK
Certificate purposes:
SSL client : No
SSL client CA : No
SSL server : Yes
SSL server CA : No

此证书仅用于服务器身份验证(普通 HTTPS)。有关详细信息,请使用 openssl x509 中的 -text 选项:

$ openssl pkcs12 -in server-only.pfx -nokeys | openssl x509 -noout -text
  [..snip..]
        X509v3 Key Usage: 
            Digital Signature, Key Encipherment
        X509v3 Extended Key Usage: 
            TLS Web Server Authentication
  [..snip..]

如果是这种情况,您将不得不要求获取标记为客户端身份验证使用的新签名证书。

于 2012-10-29T18:52:54.683 回答
3

嗯,首先要检查的是 Tomcat 是否配置正确,可以从客户端请求相关路径的证书。对于 Tomcat 6,这意味着您应该在 conf/server.xml 中配置一个连接器,如下所示:

<Connector port="443" protocol="HTTP/1.1" SSLEnabled="true"
           maxThreads="150" scheme="https" secure="true"
           keystoreFile="${user.home}/.keystore" keystorePass="password"
           truststoreFile="conf/truststore" truststorePass="password"
           clientAuth="true" sslProtocol="TLS" />

truststoreFile 和 truststorePass 很重要——如果你只添加“clientAuth=true”而不包括这两个参数,你会看到各种奇怪的行为(并且没有警告你做错了什么)。truststoreFile 必须指向一个合法的 JKS 文件,该文件列出了您信任的 CA 来签署客户端证书。如果 Tomcat 配置正确,浏览器应该会向用户弹出一个对话框,内容如下:“网站需要客户端证书”以及已导入浏览器的所有证书的列表。如果您没有看到这一点,则说明您的 Tomcat 设置有问题。

听起来您已正确设置,但值得仔细检查。此外,如果您正确设置了它,如果您在 Wireshark 中跟踪按可分辨名称列出受信任 CA 的连接,您将看到“证书请求”握手消息。同样,如果您没有看到这个,请检查您的 Tomcat 设置,最重要的是检查信任库。

接下来是检查 PKCS12 文件本身。你可以这样做:

openssl pkcs12 -in [path-to-pkcs12-file] -nokeys | openssl x509 -noout -subject -issuer

确保颁发者的专有名称与您的信任库中的trustedCaCert 条目之一匹配。使用 Java keytool 有点麻烦,但您可以使用以下命令仔细检查:

keytool -exportcert -keystore conf/truststore -alias [alias of trusted cert] | openssl x509 -noout -subject -inform der

如果所有这些都检查了,但仍然无法正常工作,那么值得使用 openssl 的 s_client 进行故障排除,因为您通常会从中获得更多故障排除信息。为此,您必须将密钥与 PKCS12 文件中的证书分开:

openssl pkcs12 -in [PKCS12 file] -out [whatever].key
openssl s_client -tls1 -connect localhost:443 -cert [whatever].key -key [whatever].key

(您可以对“-cert”和“-key”参数使用相同的文件,因为 openssl 足够聪明地在源文件中查找“BEGIN CERTIFICATE”和“BEGIN RSA PRIVATE KEY”分隔符)。我遇到了一个令人沮丧的客户端证书问题,直到我使用 s_client 并收到提醒说我的客户端证书已过期(未在其他任何地方记录或输出)之前我都无法弄清楚。

此外,您可能需要强烈考虑将您的配置转变为使用 Apache 而不是 Tomcat - Apache更加灵活,并且在 SSL 配置方面比 Tomcat 给您更多的反馈

于 2012-04-11T20:11:24.277 回答