0

I am trying to get AWS Secrets Manager to work on an older Java 7 platform. Unfortunately we're locked on Java 7 for now.

The issue I have is that Java 7 had some security issues with SSL, and most modern Java platforms are using newer cipherSuites. Thus I get the error

javax.net.ssl.SSLHandshakeException: No negotiable cipher suite

In other interfaces I've been able to solve the issue by doing an .setEnabledCipherSuites on the SSL socket.

The problem here is that the Secrets Manager client does not expose the socket (AFAICT), nor does it expose the SocketFactory. I've been trying to create a new SSLContext wrapping the stock SSLContext that will provide a custom SocketFactory but creating and installing a custom SSLContext has proven to be quite complicated.

Before I end up pulling out the rest of my hair, is there an easier way to do this?

AWS Secrets Manager uses Apache HTTP Client (httpclient-4.5.7) under the covers. Is there a static way of hooking the Apache client with a custom Socket, SocketFactory, or SSLContext? One that does not require access to the HTTPClient object (which is not exposed either).

wdtj
  • 4,554
  • 3
  • 17
  • 20
  • You should enable ssl debug output to see what ciphersuites are being sent. And make sure you have the JCE Unlimited Strength Jurisdiction Policy Files installed. – President James K. Polk Jun 18 '19 at 01:55
  • We've done that. The JCE Unlimited Strength is not quite enough, you also have to enable the Suites at the program level. If there is a way to enable them from outside the program, I've not found it. – wdtj Jun 18 '19 at 11:44
  • For https specifically there are system properties you can set from the java vm command line, see [customizing JSSE](https://docs.oracle.com/javase/8/docs/technotes/guides/security/jsse/JSSERefGuide.html#InstallationAndCustomization). Java 7 should support modern ciphersuites though. – President James K. Polk Jun 18 '19 at 12:08
  • Tried https.cipherSuites and https.protocols system property an I think you were getting at. These appear to be dependent on the http client implementation. AWS Secrets Manager uses Apache HTTP Client (httpclient-4.5.7) don't appear to use these. – wdtj Jul 10 '19 at 18:11

1 Answers1

0

After much head banging I came up with the following code:

final String ciphers[] =
    { "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA", "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256",
        "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA", "TLS_RSA_WITH_AES_128_CBC_SHA", "TLS_RSA_WITH_AES_128_CBC_SHA256",
        "TLS_RSA_WITH_AES_256_CBC_SHA256" };

final String[] protocols = new String[]
    { "TLSv1.2" };

// create and initialize an SSLContext for a custom socket factory
final SSLContext sslcontext = SSLContext.getInstance("SSL");
sslcontext.init(null, null, new SecureRandom());

// and here's our SocketFactory
final SSLConnectionSocketFactory secureSocketFactory = new SSLConnectionSocketFactory(sslcontext, protocols,
        ciphers, new DefaultHostnameVerifier());

// Create a custom AWS Client Configuration with our socket factory
final ClientConfiguration cc = new ClientConfiguration();
final ApacheHttpClientConfig acc = cc.getApacheHttpClientConfig();
acc.setSslSocketFactory(secureSocketFactory);

// Create a Secrets Manager client with our custom AWS Client Configuration
final AWSSecretsManager client = AWSSecretsManagerClientBuilder //
        .standard() //
        .withRegion(region) //
        .withClientConfiguration(cc) //
        .build();

client is then used for the requests.

wdtj
  • 4,554
  • 3
  • 17
  • 20