Embracing the Messiness in Search of Epic Solutions

Java + HTTPS: Handling ERR_SSL_WEAK_SERVER_EPHEMERAL_DH_KEY

Posted

in

PROBLEM

When accessing HTTPS links from a local application server, the modern browser throws the following error message(s):-

  • SSL received a weak ephemeral Diffie-Hellman key in Server Key Exchange handshake message. (Error code: ssl_error_weak_server_ephemeral_dh_key)
  • Server has a weak ephemeral Diffie-Hellman public key

SOLUTIONS

There are multiple solutions to this problem.

SOLUTION 1: Disable browser check

One way is to completely disable this check on the browser.

For example, in Firefox, go to about:config and set security.ssl3.dhe_rsa_aes_128_sha and security.ssl3.dhe_rsa_aes_256_sha to false.

The downside is the browser is exposed to Logjam attacks.

SOLUTION 2: Use Java 8

The easiest solution is to use Java 8 because it has better cipher support.

The downside is sometimes using Java 8 is not an option if you don’t have control on the application server.

SOLUTION 3: Use Bouncy Castle

If you are using Java 6 or Java 7, you can download Bouncy Castle crypto implementation and store them in $JAVA_HOME/jre/lib/ext.

Then, register this provider in $JAVA_HOME/jre/lib/security/java.security, for example:-

#
# List of providers and their preference orders (see above):
#
# MacOSX added com.apple.crypto.provider.Apple as #3
security.provider.1=sun.security.pkcs11.SunPKCS11 ${java.home}/lib/security/sunpkcs11-macosx.cfg
security.provider.2=sun.security.provider.Sun
security.provider.3=com.apple.crypto.provider.Apple
security.provider.4=sun.security.rsa.SunRsaSign
security.provider.5=com.sun.net.ssl.internal.ssl.Provider
security.provider.6=com.sun.crypto.provider.SunJCE
security.provider.7=sun.security.jgss.SunProvider
security.provider.8=com.sun.security.sasl.Provider
security.provider.9=org.jcp.xml.dsig.internal.dom.XMLDSigRI
security.provider.10=sun.security.smartcardio.SunPCSC
security.provider.11=org.bouncycastle.jce.provider.BouncyCastleProvider

The downside is if your team is doing local application development, all team members have to perform these steps on their machines too.

SOLUTION 4: Disable all weak Diffie-Hellman ciphers

Another solution is to configure the server by disabling all the weak Diffie-Hellman ciphers.

You can either enable the strong ciphers or disable the weak ciphers.

However, it is preferable (in my opinion) to disable weak ciphers so that newer (and stronger) ciphers will automatically be included when Java version is updated in the future.

Here is a working example for Jetty server:-

<plugin>
    <groupid>org.mortbay.jetty</groupid>
    <artifactid>jetty-maven-plugin</artifactid>
    <version>8.1.16.v20140903</version>
    <configuration>
        <stopkey>jetty-stop-key</stopkey>
        <stopport>7778</stopport>
        <scanintervalseconds>1</scanintervalseconds>
        <requestlog implementation="org.eclipse.jetty.server.NCSARequestLog">
            <extended>true</extended>
            <logtimezone>CST</logtimezone>
        </requestlog>
        <webapp>
            <contextpath>/${project.artifactId}</contextpath>
            <webinfincludejarpattern>.*/.*jsp-api-[^/]\.jar$|./.*jsp-[^/]\.jar$|./.*taglibs[^/]*\.jar$</webinfincludejarpattern>
        </webapp>
        <connectors>
            <connector implementation="org.eclipse.jetty.server.bio.SocketConnector">
                <port>7777</port>
            </connector>
            <connector implementation="org.eclipse.jetty.server.ssl.SslSocketConnector">
                <port>7443</port>
                <keystore>${project.basedir}/src/main/config/keystore.jks</keystore>
                <keypassword>jetty8</keypassword>
                <password>jetty8</password>
                <excludeciphersuites>
                    <excludeciphersuites>SSL_RSA_WITH_DES_CBC_SHA</excludeciphersuites>
                    <excludeciphersuites>SSL_DHE_RSA_WITH_DES_CBC_SHA</excludeciphersuites>
                    <excludeciphersuites>SSL_DHE_DSS_WITH_DES_CBC_SHA</excludeciphersuites>
                    <excludeciphersuites>SSL_RSA_EXPORT_WITH_RC4_40_MD5</excludeciphersuites>
                    <excludeciphersuites>SSL_RSA_EXPORT_WITH_DES40_CBC_SHA</excludeciphersuites>
                    <excludeciphersuites>SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA</excludeciphersuites>
                    <excludeciphersuites>SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA</excludeciphersuites>
                    <excludeciphersuites>SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA</excludeciphersuites>
                    <excludeciphersuites>TLS_DHE_RSA_WITH_AES_256_CBC_SHA256</excludeciphersuites>
                    <excludeciphersuites>TLS_DHE_DSS_WITH_AES_256_CBC_SHA256</excludeciphersuites>
                    <excludeciphersuites>TLS_DHE_RSA_WITH_AES_256_CBC_SHA</excludeciphersuites>
                    <excludeciphersuites>TLS_DHE_DSS_WITH_AES_256_CBC_SHA</excludeciphersuites>
                    <excludeciphersuites>TLS_DHE_RSA_WITH_AES_128_CBC_SHA256</excludeciphersuites>
                    <excludeciphersuites>TLS_DHE_DSS_WITH_AES_128_CBC_SHA256</excludeciphersuites>
                    <excludeciphersuites>TLS_DHE_RSA_WITH_AES_128_CBC_SHA</excludeciphersuites>
                    <excludeciphersuites>TLS_DHE_DSS_WITH_AES_128_CBC_SHA</excludeciphersuites>
                </excludeciphersuites>
            </connector>
        </connectors>
    </configuration>
</plugin>

The downside is the server configuration gets a little lengthy.

Tags:

Comments

Leave a Reply