0

Diving right into the code, here is a method I am using to create an SSLContext

private static SSLContext createContext(String keystore_path, String truststore_path, String password) throws Exception {
        final KeyStore key_store = KeyStore.getInstance("JKS");
        final KeyStore trust_store = KeyStore.getInstance("JKS");

        final char[] passphrase = password.toCharArray();

        key_store.load(new FileInputStream(keystore_path), passphrase);
        trust_store.load(new FileInputStream(truststore_path), passphrase);

        KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");
        kmf.init(key_store, passphrase);

        TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509");
        tmf.init(trust_store);

        SSLContext ssl_ctx = SSLContext.getInstance("TLSv1");
        ssl_ctx.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);
        return ssl_ctx;
    }

The resulting SSLContext is then used to create SSLEngine instances which I use to encrypt network communications. Now that this is out of the way, I have tried 3 different ways to create an SSLContext, and only one works. I would like to understand why the 2 others fail, and how to make them work (if possible). Both the failing ones fail during the SSL handshake.

Method #1 (works)

My SSL handshakes work when using my own truststore and keystore like so:

ssl_ctx = createContext(my_keystore_file, my_truststore_filepath, my_password);

Method #2 (does NOT work)

final String default_store_path = System.getProperties().getProperty("java.home") + File.separator + "lib"
                + File.separator + "security" + File.separator + "cacerts";
        final String default_password = "changeit";
        ssl_ctx = createContext(default_store_path, default_store_path, default_password);

I get the following exception in this case:

Exception in thread "main" javax.net.ssl.SSLHandshakeException: no cipher suites in common
    at java.base/sun.security.ssl.Alert.createSSLException(Alert.java:131)
    at java.base/sun.security.ssl.Alert.createSSLException(Alert.java:117)
    at java.base/sun.security.ssl.TransportContext.fatal(TransportContext.java:307)
    ...

Method #3 (does NOT work)

ssl_ctx = SSLContext.getDefault();

But this time I am getting the following exception:

Exception in thread "main" javax.net.ssl.SSLHandshakeException: No available authentication scheme
    at java.base/sun.security.ssl.Alert.createSSLException(Alert.java:131)
    at java.base/sun.security.ssl.Alert.createSSLException(Alert.java:117)
    at java.base/sun.security.ssl.TransportContext.fatal(TransportContext.java:307)

On a side note, I am not interested in using a third party library such as Grizzly. Thank you!

MarkoPaulo
  • 474
  • 4
  • 19
  • 2
    `cacerts` doesn't contain any private keys, and all the anonymous cipher suites are disabled by default, hence 'no cipher suites in common'. Your own keystore appears to contain a private key. – user207421 Aug 07 '20 at 00:01
  • @MarquisofLorne thanks for the help! What about method#3, why do I get "No available authentication scheme"? – MarkoPaulo Aug 07 '20 at 02:36
  • 1
    Because the default context defaults to cacerts for the truststore but NO (= empty) keystore unless system properties `javax.net.ssl.keyStore*` are set, thus it has no client-key-and-cert to use for authentication if/when the servers requests that. – dave_thompson_085 Aug 07 '20 at 05:22

0 Answers0