2

I'm trying to use self signed certificates (ie where the Subject and the Issuer are both the same) with x509 client authentication.

My understanding is that I need to make two sets of key pairs and put them into the appropriate keyStore.jks for the client and the server.

Then I need to make each side "trust" the CA that signed the certificates. Since these are self-signed, that seems to mean I need to put the certificate also into the trustStore.jks for both sides (ie the client's cert should go into the server's trustStore, and opposite for the server's cert).

This is how I did it:

#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's Connector is configured like

     <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"
           />

And the client is run like this:

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

Ultimately the client spewls a lot of info, but here you can see that the client apparently refuses to send it's client certificate

*** 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>
***

I read that to mean: "Server is saying hello and asking for a client certificate (because of the tomcat clientAuth=true setting). That certificate must be signed by one of the listed CAs (ie CN=root), but then the client says no suitable certificate is found.

mlathe
  • 2,334
  • 1
  • 22
  • 40
  • Looks good to me. You can maybe test sides indivdually with openssl: http://stackoverflow.com/a/21060241/995891 and maybe that yields a better error message – zapl Nov 11 '16 at 00:11
  • What is the signature algorithm of the client certficate? And is it one of those listed in the CertificateRequest message? – user207421 Nov 11 '16 at 00:42
  • @EJP from the clientKeyStore.jks i see `Signature algorithm name: SHA256withRSA` via the `keytool -list` command. From the client's verbose logging I can see `Supported Signature Algorithms: SHA512withECDSA, SHA512withRSA, SHA384withECDSA, SHA384withRSA, SHA256withECDSA, ___ SHA256withRSA ___, SHA256withDSA, SHA224withECDSA, SHA224withRSA, SHA224withDSA, SHA1withECDSA, SHA1withRSA, SHA1withDSA` ... so yes... they match. – mlathe Nov 11 '16 at 00:49
  • (Just FYI... for now the client and the server are running on the same host and with the same JRE) – mlathe Nov 11 '16 at 00:50
  • Perhaps you could try to add `-ext BasicConstraints:critical="ca:true"` to the `keytool -genkey` command that generates the client cert, to make it a CA certificate too. – Bruno Nov 11 '16 at 01:04
  • maybe get valid certificate https://myfreessl.com/ – Novkovski Stevo Bato Nov 11 '16 at 01:58
  • @Bruno, no.. that didn't help. I think the cert is being trusted as a CA just fine. Above in my `CertificateRequest` snippet you can see the server is saying (i think) "please send me a cert that is signed by one of the following CA certs". CN=root is the client cert, so that should be the CA for the selfsigned cert – mlathe Nov 14 '16 at 17:11
  • One thing that I can't wrap my head around is how to debug the KeyStore. I don't see any reference to it being read. I see the TrustStore getting read via an output like `trustStore is: /home/mlathe/NetBeansProjects/foo/clientTrustStore.jks`. In tomcat I see an output like this that implies it is reading its keystore file: `found key for : tomcat` – mlathe Nov 14 '16 at 17:16

0 Answers0