我正在尝试使用x509客户端身份验证的自签名证书(即主题和颁发者都相同)。
我的理解是我需要制作两组密钥对,并将它们放入客户端和服务器的相应keyStore.jks中。
然后我需要让每一方“信任”签署证书的CA.由于这些是自签名的,这似乎意味着我需要将证书也放入双方的trustStore.jks中(即客户端的证书应该进入服务器的trustStore,而服务器的证书则相反)。
我就这样做了:
#make selfsigned Tomcat cert
keytool -genkey -keyalg RSA -validity 365 -keysize 2048 -alias tomcat -keystore $TOMCAT_ROOT/conf/keyStore.jks -storepass changeit -dname 'CN=localhost' -keypass changeit
#don't want to import the whole private key... just the certificate part
# we're trying to make the client trust the server's CA
keytool -exportcert -alias tomcat -keystore $TOMCAT_ROOT/conf/keyStore.jks -storepass changeit -file tomcat.crt
keytool -importcert -alias tomcat -keystore clientTrustStore.jks -storepass clientPassword -file tomcat.crt -noprompt
#make the client key pair
keytool -genkey -keyalg RSA -validity 365 -keysize 2048 -alias client -keystore clientKeyStore.jks -storepass clientPassword -dname 'CN=root' -keypass clientPassword
#make sure tomcat can trust the client's CA
keytool -exportcert -alias client -keystore clientKeyStore.jks -storepass clientPassword -file client.crt
keytool -importcert -alias client -keystore $TOMCAT_ROOT/conf/trustStore.jks -storepass changeit -file client.crt -noprompt
Tomcat的连接器配置为
<Connector port="8443"
protocol="org.apache.coyote.http11.Http11NioProtocol"
SSLEnabled="true"
maxThreads="150"
scheme="https"
secure="true"
keystoreFile="snip/conf/keyStore.jks"
keystorePass="changeit"
truststoreFile="snip/conf/trustStore.jks"
truststorePass="changeit"
enableLookups="true"
clientAuth="true"
sslEnabledProtocols="TLSv1.2,TLSv1.1"
ciphers="TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256, TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, TLS_DHE_RSA_WITH_AES_128_CBC_SHA, TLS_RSA_WITH_AES_128_CBC_SHA256, SSL_RSA_WITH_3DES_EDE_CBC_SHA"
/>
客户端运行如下:
java -Djavax.net.ssl.trustStore=clientTrustStore.jks \
-Djavax.net.ssl.trustStorePassword=clientPassword \
-Djavax.net.ssl.keyStore=clientKeyStore.jks \
-Djavax.net.ssl.keyStorePassword=clientPassword \
-Djavax.net.debug=ssl foo.bar.Main
最终客户会发出很多信息,但在这里您可以看到客户显然拒绝发送客户端证书
*** ServerHello, TLSv1.2
--snip--
*** CertificateRequest
Cert Types: RSA, DSS, ECDSA
Supported Signature Algorithms: SHA512withECDSA, SHA512withRSA, SHA384withECDSA, SHA384withRSA, SHA256withECDSA, SHA256withRSA, SHA256withDSA, SHA224withECDSA, SHA224withRSA, SHA224withDSA, SHA1withECDSA, SHA1withRSA, SHA1withDSA
Cert Authorities:
<CN=root>
*** ServerHelloDone
Warning: no suitable certificate found - continuing without client authentication
*** Certificate chain
<Empty>
***
我读到这意味着:“服务器正在打招呼并要求提供客户端证书(因为tomcat clientAuth = true设置)。该证书必须由其中一个列出的CA(即CN = root)签名,但是然后客户说没有找到合适的证书。