java.security.SignatureException: Signature does not match

Solution 1:

I finally found the problem: The SignatureException does not indicate that the issuer is unknown to the client. In that case a CertPathBuilderException would be thrown.

The SignatureException was actually caused by not having the self-signed certificate imported as trusted certificate which must be done by the additional parameter -trustcacerts.

To answer the question why someone should want to trust a self signed certificate: The server is used for test purposes for automated client tests connecting to the server over HTTPS.

Solution 2:

The Signature does not match error is the symptom that the server identity is unknown to the client, ie the client truststore does not have the server certificate.

Create the server certificate and add it to a keystore:

keytool -genkey -noprompt -alias "$alias" -dname "CN=$dname_cn, OU=$dname_ou, O=$dname_o, L=$dname_l, S=$dname_s, C=$dname_c" -keystore "$keystore" -storepass "$storepass" -keypass "$keypass"

and export it for the client into a truststore:

keytool -export -alias "$alias" -storepass "$storepass" -file "$alias".cer -keystore "$keystore"

If you want 2-way SSL then you have to repeat this twice, inverting, they both must know each other.

Now the tricky part is to build an SSLContext correctly and configure your client and server with it.

In Grizzly I do:

SSLContextConfigurator sslContextConfigurator = new SSLContextConfigurator();

// set up security context
sslContextConfigurator.setKeyStoreFile(configuration.getKeystore()); // contains the server keypair
sslContextConfigurator.setKeyStorePass(configuration.getKeystorePassword());
sslContextConfigurator.setKeyStoreType(configuration.getKeystoreType());
sslContextConfigurator.setKeyPass(configuration.getKeystoreKeypass());
sslContextConfigurator.setTrustStoreFile(configuration.getTruststore()); // contains the list of trusted certificates
sslContextConfigurator.setTrustStorePass(configuration.getTruststorePassword());
sslContextConfigurator.setTrustStoreType(configuration.getTruststoreType());
if (!sslContextConfigurator.validateConfiguration(true))
    throw new Exception("Invalid SSL configuration");

For advanced debugging do not forget System.setProperty("javax.net.debug", "all");

Solution 3:

-keypass password 

Get rid of this parameter. The mechanism that supports javax.net.ssl.keyStore and javax.net.ssl.keyStorePassword doesn't support key passwords, only keystore passwords.