OpenJDK Runtime Environment (build 1.8.0_151-b12)
OpenJDK 64-Bit Server VM (build 25.151-b12, mixed mode)
I have a server and client, both running this same version of the JDK. The server is configured with the following keysize restriction set in the java.security file:
jdk.tls.disabledAlgorithms=SSLv3, DH keysize < 2048, EC keySize < 244
I am trying to connect to this server using the code below.
When I run the code using Eclipse, I am passing the following JVM arguments:
-Djdk.tls.ephemeralDHKeySize=2048
-Dhttps.cipherSuites=TLS_DHE_RSA_WITH_AES_256_CBC_SHA256
-Djavax.net.debug=ssl
The connection fails with:
javax.net.ssl.SSLHandshakeException: Remote host closed connection during handshake
The debug output shows:
*** Diffie-Hellman ServerKeyExchange DH Modulus: { 255, 255, 255, 255, 255, 255, 255, 255, 201, 15, 218, 162, 33, 104, 194, 52, 196, 198, 98, 139, 128, 220, 28, 209, 41, 2, 78, 8, 138, 103, 204, 116, 2, 11, 190, 166, 59, 19, 155, 34, 81, 74, 8, 121, 142, 52, 4, 221, 239, 149, 25, 179, 205, 58, 67, 27, 48, 43, 10, 109, 242, 95, 20, 55, 79, 225, 53, 109, 109, 81, 194, 69, 228, 133, 181, 118, 98, 94, 126, 198, 244, 76, 66, 233, 166, 55, 237, 107, 11, 255, 92, 182, 244, 6, 183, 237, 238, 56, 107, 251, 90, 137, 159, 165, 174, 159, 36, 17, 124, 75, 31, 230, 73, 40, 102, 81, 236, 230, 83, 129, 255, 255, 255, 255, 255, 255, 255, 255 } DH Base: { 2 } Server DH Public Key: { 135, 132, 170, 17, 75, 190, 175, 214, 182, 199, 168, 72, 222, 87, 8, 157, 56, 65, 108, 79, 223, 183, 37, 222, 104, 15, 83, 46, 95, 155, 84, 32, 91, 237, 225, 148, 215, 145, 250, 214, 151, 110, 126, 225, 23, 86, 112, 27, 84, 58, 44, 250, 204, 92, 157, 82, 212, 219, 81, 73, 55, 226, 193, 82, 73, 113, 155, 34, 38, 150, 211, 85, 208, 110, 202, 233, 23, 112, 157, 3, 129, 0, 140, 74, 123, 47, 194, 106, 152, 245, 245, 154, 18, 244, 143, 79, 132, 4, 236, 228, 244, 102, 147, 103, 125, 136, 195, 133, 176, 245, 231, 185, 95, 164, 27, 18, 204, 207, 14, 7, 87, 53, 251, 174, 93, 95, 164, 103 } Anonymous *** ServerHelloDone *** ClientKeyExchange, DH DH Public key: { 63, 242, 1, 213, 26, 167, 141, 18, 206, 161, 228, 41, 83, 229, 217, 160, 154, 81, 75, 102, 111, 72, 32, 63, 100, 46, 188, 140, 16, 235, 88, 230, 108, 156, 1, 123, 207, 66, 23, 170, 137, 172, 107, 128, 32, 37, 169, 6, 135, 208, 180, 251, 118, 201, 27, 141, 217, 102, 112, 30, 90, 130, 105, 216, 197, 43, 107, 0, 212, 160, 64, 246, 186, 100, 114, 142, 138, 108, 32, 107, 134, 109, 122, 217, 59, 121, 22, 168, 209, 99, 200, 159, 141, 202, 248, 152, 240, 37, 215, 17, 50, 246, 158, 35, 131, 195, 128, 104, 227, 221, 147, 192, 222, 208, 56, 129, 161, 53, 76, 197, 199, 249, 227, 8, 64, 161, 192, 134 } main, WRITE: TLSv1.2 Handshake, length = 134
Correct me if I'm wrong, but I believe this shows that my client connection is attempting to use a key size of 1024 and the server is (correctly) rejecting the connection during handshake. Why isn't the JVM honoring the jdk.tls.ephemeralDHKeySize value? I believe the cipher is a non-exportable cipher and according to the JSSE Reference Guide should be affected by the ephemeral key size property.
Any help in understanding this will be truly appreciated.
Code:
final TrustManager[] trustManagers = { new X509TrustManager() { @Override public java.security.cert.X509Certificate[] getAcceptedIssuers() { return null; } @Override public void checkClientTrusted(X509Certificate[] arg0, String arg1) throws CertificateException { // No-op } @Override public void checkServerTrusted(X509Certificate[] arg0, String arg1) throws CertificateException { // No-op } } }; final SSLContext sc = SSLContext.getInstance("TLSv1.2"); sc.init(null, trustManagers, new java.security.SecureRandom()); HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory()); final HostnameVerifier hostnameVerifier = new HostnameVerifier() { @Override public boolean verify(String hostname, SSLSession session) { return true; } }; HttpsURLConnection.setDefaultHostnameVerifier(hostnameVerifier); URL url = new URL("https", "<ip of server>", 8443, "/"); HttpsURLConnection conn = (HttpsURLConnection) url.openConnection(); conn.connect(); try (final InputStream is = conn.getInputStream()) { System.out.println(conn.getCipherSuite()); // no-op }