Modern security standards require at least 2048-bit Diffie-Hellman (DH) parameters to prevent Logjam attacks. The default Java keystore doesn't provide direct keytool commands for DH parameter generation, but we can work around this limitation.
Since keytool doesn't support DH parameter generation directly, we'll generate them with OpenSSL first:
openssl dhparam -out dhparams.pem 2048
This creates a file named dhparams.pem
containing 2048-bit DH parameters.
Java requires DH parameters in PKCS#8 format. Convert the OpenSSL output:
openssl pkcs8 -topk8 -inform PEM -outform DER -in dhparams.pem -out dhparams.der -nocrypt
For JBoss 5.1.0.GA, modify your server.xml or standalone.xml:
<Connector port="8443" protocol="HTTP/1.1" SSLEnabled="true" maxThreads="150" scheme="https" secure="true" sslProtocol="TLS" keystoreFile="conf/keystore.jks" keystorePass="changeit" dhParamFile="conf/dhparams.der" ciphers="TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,..." />
For those who prefer pure Java solutions, here's how to generate DH parameters programmatically:
import javax.crypto.spec.DHParameterSpec; import java.security.AlgorithmParameterGenerator; import java.security.AlgorithmParameters; public class DHGenerator { public static void main(String[] args) throws Exception { AlgorithmParameterGenerator paramGen = AlgorithmParameterGenerator.getInstance("DH"); paramGen.init(2048); AlgorithmParameters params = paramGen.generateParameters(); DHParameterSpec dhSpec = params.getParameterSpec(DHParameterSpec.class); System.out.println("Prime: " + dhSpec.getP()); System.out.println("Generator: " + dhSpec.getG()); } }
After implementation, test your server with:
openssl s_client -connect yourserver:443 -cipher "EDH" -msg
Look for "Server Temp Key: DH, 2048 bits" in the output.
2048-bit DH parameters will impact TLS handshake performance. Consider enabling session resumption in your JBoss configuration to mitigate this:
<SSL> <attribute name="allowUnsafeRenegotiation">false</attribute> <attribute name="sessionCacheSize">20480</attribute> <attribute name="sessionTimeout">86400</attribute> </SSL>
When running security tests on web servers (particularly older versions like JBoss 5.1.0.GA), you might encounter warnings about weak Diffie-Hellman parameters. The weakdh.org test specifically recommends generating new 2048-bit parameters to maintain secure key exchanges.
While Java keytool is excellent for managing keystores and certificates, it doesn't directly support generating standalone Diffie-Hellman parameters. Here's why:
- Keytool primarily handles key pairs and certificates
- DH parameter generation requires cryptographic operations beyond keytool's scope
- The JDK's internal crypto libraries handle DH operations differently
Here are two practical methods to generate 2048-bit DH parameters for your Java web server:
Method 1: Using OpenSSL
The most straightforward approach uses OpenSSL:
openssl dhparam -out dhparams.pem 2048
This generates a PEM file containing the parameters. You can then configure your JBoss server to use this file.
Method 2: Programmatic Generation in Java
For a pure Java solution, you can generate parameters programmatically:
import javax.crypto.spec.DHParameterSpec; import java.security.AlgorithmParameterGenerator; import java.security.AlgorithmParameters; public class DHParamGenerator { public static void main(String[] args) throws Exception { AlgorithmParameterGenerator paramGen = AlgorithmParameterGenerator.getInstance("DH"); paramGen.init(2048); AlgorithmParameters params = paramGen.generateParameters(); DHParameterSpec dhSpec = params.getParameterSpec(DHParameterSpec.class); System.out.println("Prime (p): " + dhSpec.getP()); System.out.println("Base (g): " + dhSpec.getG()); System.out.println("L value: " + dhSpec.getL()); } }
For JBoss 5.1.0.GA, you'll need to modify the server's SSL connector configuration. Add these parameters to your server.xml or equivalent configuration file:
<Connector port="8443" protocol="HTTP/1.1" SSLEnabled="true" maxThreads="150" scheme="https" secure="true" clientAuth="false" sslProtocol="TLS" ciphers="TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, TLS_DHE_RSA_WITH_AES_128_GCM_SHA256,TLS_DHE_DSS_WITH_AES_128_GCM_SHA256, TLS_DHE_RSA_WITH_AES_256_GCM_SHA384" useServerCipherSuitesOrder="true"/>
After implementation, verify your settings using:
openssl s_client -connect yourserver:443 -cipher "EDH" | grep "Server Temp Key"
You should see output indicating 2048-bit DH parameters are in use.
- Regularly rotate your DH parameters (annually recommended)
- Consider upgrading to 3072-bit parameters for long-term security
- Monitor for new vulnerabilities in DH implementations
- Keep your Java version updated for the latest crypto improvements