嗯,首先要检查的是 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 给您更多的反馈。