« Defending against the BREACH attack | Main | Is BEAST still a threat? »

Increasing DHE strength on Apache 2.4.x

August 15, 2013

Update (13 May 2015): Apache 2.2.30 (not yet released at the time of writing) will also support configurable DH parameter strength, in the same way Apache 2.4.x does.

Update (26 Nov 2013): Apache 2.4.7, released today, has been improved to automatically select appropriate DH parameters, using the strength of the server key as guidance. Thus, there is no need to modify the source code any more. The improvements are explained in the CHANGES file, and in the SSLCertificateFile documentation.

Update (18 Oct 2013): Since I wrote this post, Apache improved DH parameter handling. The trunk version now automatically selects appropriate DH parameter strength based on the strength of the private key. The bug report now includes a backport to 2.4.x.

Some users of older versions of the Apache web server, who are trying to get their Forward Secrecy configuration just right usually run into a brick wall when they determine that Apache won't use Diffie-Hellman parameters stronger than 1024 bits. This is because Apache leaves the business of DH configuration to OpenSSL, and 1024 bits is just what you get by default (for the stronger suites; the weaker ones use 512 bits).

Other web servers expose configuration options that allow you to increase the DH strength, but Apache does not. But, if you went through the hassle of installing Apache from source code (as I described in my previous blog post), there's an easy fix for this problem. Apache Software Foundation's bug #49559 ("Patch to add user-specified Diffie-Hellman parameters") contains a patch that introduces a new configuration directive, called SSLDHParametersFile, that adds the missing functionality to Apache httpd 2.4.x.

The bug is more than 3 years old, even though the code seems straightforward. The latest version of the patch was made against httpd 2.4.2, just over a year ago. I've tested it against httpd 2.4.6, and, with a hiccup, it appears to work as advertised.

The hiccup is that the patch won't compile as-is; a trivial change is required. If you're a programmer, you'll have no problem understanding the error and finding the fix from looking at the rest of the mod_ssl code. And if you don't want to do even that, you can download my version. (Disclaimer: I just made it compile, but didn't otherwise read or review the code. Use at your own risk.)

Assuming the starting point is the pristine source code tree of httpd 2.4.6, apply the patch like this:

$ cd httpd-2.4.6
$ patch -p1 < /path/to/patch-49559-for-2.4.6.diff
patching file modules/ssl/mod_ssl.c
patching file modules/ssl/ssl_engine_config.c
Hunk #2 succeeded at 189 (offset 6 lines).
Hunk #3 succeeded at 318 (offset 15 lines).
Hunk #4 succeeded at 801 (offset 36 lines).
patching file modules/ssl/ssl_engine_init.c
Hunk #1 succeeded at 994 (offset 44 lines).
Hunk #2 succeeded at 1192 (offset -1 lines).
Hunk #3 succeeded at 1205 (offset -1 lines).
Hunk #4 succeeded at 1769 (offset 20 lines).
patching file modules/ssl/ssl_engine_pphrase.c
patching file modules/ssl/ssl_private.h
Hunk #2 succeeded at 546 (offset 18 lines).
Hunk #3 succeeded at 573 (offset 18 lines).
Hunk #4 succeeded at 744 (offset 28 lines).
patching file modules/ssl/ssl_util_ssl.c
patching file modules/ssl/ssl_util_ssl.h

From here, compile and install as usually.

To use stronger DH parameters, you first need to create a special parameter file with the desired strength:

$ openssl dhparam -out dh2048.pem 2048

The process will take some time and you'll see lots of output on your screen. (If you're curious what the various characters mean, have a look here.) Then you need to add this directive to your Apache configuration:

SSLDHParametersFile /path/to/dh2048.pem

That's all. Now you only need to restart the web server and test it using the SSL Labs test.

Update (15 Aug 2013): As Michael Reschly reminded me, increasing DH strength can cause interoperability issues. In particular, Java is known not to support DH parameters above 1024 bits. Here's a Stack Overflow thread that contains more information. The issue has been resolved in the (not yet released) Java 8.

Update (19 Aug 2013): Ryan Hurst also wanted me to tell you that Windows crypto libraries don't support DH parameters stronger than 1024 bits. (Windows 8.1 might appears to actually support stronger DHE keys.) The only browser that could be affected by this is Internet Explorer. Other browsers running on Windows use their own crypto, and do not have this limitation. But even with IE users—as Reschly pointed out via Twitter—the DH limitation should not be a problem, for two reasons. First, if you configure Forward Secrecy correctly using ECDHE suites (as I discussed in my previous post), IE will always use ECDHE. Second, IE does not support DHE in combination with RSA, and will never negotiate a DHE suite, anyway.

Update (13 May 2015): The original post incorrectly stated that Apache supported only 1024-bit DH parameters because it delegated DH parameter handling to OpenSSL. That is incorrect. The limit was in the Apache code. Thanks to Richard Moore for pointing this out.

MY BOOK: If you like this blog post, you will love Bulletproof SSL and TLS. For system administrators, developers, and IT security professionals, this book provides a comprehensive coverage of the ever-changing field of SSL/TLS and Internet PKI and will teach you everything you need to know to protect your systems from eavesdropping and impersonation attacks. It's available now.