Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to configure SSL cipher suites for a Java HTTPS *server*?

Tags:

java

ssl

okhttp

Note: this question has been asked numerous times for Java HTTPS clients; my question is about configuring a server.

I'm trying to use MockWebServer to test my OkHttpClient configuration. The real web server my code hits just dropped TLS v1.0 support, so I'm changing my code to use TLS v1.2 and use the server's preferred cipher suites. I'd like to test this change with an in-memory web server that mimics the real server, but I can't figure out how to configure a SSLContext in my test with a specific list of cipher suites. (All the methods I need to access are pretty well protected inside of SSLContextImpl and its inner classes.)

The best I've been able to figure out is completely wrapping a SSLServerSocketFactory, overriding the 4 createServerSocket() methods, and calling setEnabledCipherSuites() on the SSLServerSocket before returning it, similar to how this answer did with SSLSocketFactoryEx on the client: https://stackoverflow.com/a/23365536/278800

It's frustrating that using a specific TLS version is as simple as calling e.g. SSLContext.getInstance("TLSv1.2"), but there isn't a similarly easy way to configure the cipher suites.

like image 284
Steve K Avatar asked Jul 10 '18 20:07

Steve K


People also ask

How do I add a cipher suite in Windows server?

To add cipher suites, either deploy a group policy or use the TLS cmdlets: To use group policy, configure SSL Cipher Suite Order under Computer Configuration > Administrative Templates > Network > SSL Configuration Settings with the priority list for all cipher suites you want enabled.


1 Answers

The way I ended up doing it was to wrap the underlying SSLSocketFactory, and call sslSocket.setEnabledCipherSuites(..) on the SSLSocket before returning it, like so:

final class MySSLSocketFactory extends SSLSocketFactory {
    final SSLSocketFactory wrappedSSLSocketFactory;

    MySSLSocketFactory(SSLSocketFactory wrappedSSLSocketFactory) {
        this.wrappedSSLSocketFactory = wrappedSSLSocketFactory;
    }

    @Override
    public String[] getDefaultCipherSuites() {
        return getMyCipherSuites();
    }

    @Override
    public String[] getSupportedCipherSuites() {
        return getMyCipherSuites();
    }

    @Override
    public Socket createSocket(Socket s, String host, int port, boolean autoClose) throws IOException {
        final SSLSocket sslSocket = (SSLSocket) wrappedSSLSocketFactory.createSocket(s, host, port, autoClose);

        // change the supported cipher suites on the socket, *before* it's returned to the client
        sslSocket.setEnabledCipherSuites(getMyCipherSuites());

        return sslSocket;
    }

    // other overloaded createSocket() methods do the same

    private String[] getMyCipherSuites() {
        // TODO: change this to return whatever cipher suites you want the server to use, from CipherSuite
        return new String[] {...};
    }
}
like image 52
Steve K Avatar answered Nov 15 '22 11:11

Steve K