DH Parameters Generator — Free OpenSSL DHParam Command Builder

Build the openssl dhparam command for Diffie-Hellman key exchange. Required for nginx ssl_dhparam and Apache SSLOpenSSLConfCmd DHParameters when using TLS 1.2 DHE cipher suites.

Est. time: ~30 seconds
Run this on your server
openssl dhparam -out dhparam.pem 2048
Faster (-dsaparam) variant
# Use -dsaparam for ~10x faster generation (still safe per RFC 7919)
openssl dhparam -dsaparam -out dhparam.pem 2048

# Or the standard (slower) form:
openssl dhparam -out dhparam.pem 2048

Note on TLS 1.3: TLS 1.3 does not use dhparam — it's only needed for TLS 1.2 with DHE cipher suites. If your config is TLS 1.3 only (Mozilla Modern), skip this step.

2048-bit: Recommended default. Fast to generate, more than enough security against current and near-future attackers.

nginx
# /etc/nginx/sites-available/example.com
server {
    listen 443 ssl http2;
    # ... cert config ...
    ssl_dhparam /etc/ssl/dhparam.pem;
}
Apache 2.4.7+
# Apache 2.4.7+ (httpd.conf or sites-available)
SSLOpenSSLConfCmd DHParameters "/etc/ssl/dhparam.pem"

After deploying:

nginx: sudo nginx -t && sudo nginx -s reload

Apache: sudo apachectl configtest && sudo apachectl graceful

Verify: openssl s_client -connect example.com:443 -cipher DHE-RSA-AES256-GCM-SHA384 — the Server Temp Key line should report DH, 2048 bits.

What is a DH Parameters Generator?

A DH parameters generator creates the prime p and generator g values used by Diffie-Hellman key exchange in TLS. The OpenSSL dhparam command picks a random safe prime of the requested size — 2048, 3072, or 4096 bits — and writes it as PEM. Web servers load this file at start-up and reuse it for every TLS 1.2 connection that negotiates a DHE_RSA cipher suite.

This tool builds the exact command for your bit size and output filename, plus the nginx / Apache directives to wire up the result. The command runs on your server (or laptop) — nothing is generated server-side.

How to generate DH parameters — 4 steps

  1. Pick bit size. 2048 for almost every site. 3072 if you want extra margin without paying ~30 min of CPU. 4096 only for strict compliance reasons.
  2. Set output filename. dhparam.pem is the convention. Use dhparam.pem in commands to match what your nginx/Apache config will reference.
  3. Run the openssl command. On the server (or anywhere — the file is not secret). 2048 finishes in ~30 seconds; 4096 can take 30 minutes on a small VM.
  4. Wire it up. Move dhparam.pem into /etc/ssl/, add ssl_dhparam (nginx) or SSLOpenSSLConfCmd DHParameters (Apache), reload, verify with openssl s_client.

Sample output

# Run on your server (CPU-bound, takes ~30 sec for 2048)
$ openssl dhparam -out dhparam.pem 2048
Generating DH parameters, 2048 bit long safe prime
............................................................+
.................+
....................................+
.....................+

# Result: dhparam.pem (PEM, 2048-bit safe prime)
$ cat dhparam.pem
-----BEGIN DH PARAMETERS-----
MIIBCAKCAQEA//////////+t+FRYortKmq/cViAnPTzx2LnFg84tNpWp4TZBFGQz
+8yTnc4kmz75fS/jY2MMddj2gbICrsRhetPfHtXV/WVhJDP1H18GbtCFY2VVPe0a
... (lines elided) ...
-----END DH PARAMETERS-----

Forward Secrecy for TLS 1.2

DH parameters power the DHE cipher suites — every TLS 1.2 session gets a unique shared secret, so even if your private key is later stolen, past traffic stays encrypted.

Time Estimates Built-in

See the realistic generation time for each bit size before you start. 2048 takes seconds; 4096 can take 30 minutes on a small VM — plan accordingly.

nginx + Apache Snippets

Get the matching ssl_dhparam (nginx) and SSLOpenSSLConfCmd (Apache) directives to paste straight into your config — no syntax hunting.

Common use cases

  • check_circleDeploying nginx with the Mozilla Intermediate TLS profile (requires ssl_dhparam)
  • check_circleHardening Apache 2.4.7+ with Apache SSLOpenSSLConfCmd DHParameters
  • check_circleReplacing the default 1024-bit DH parameters that ship with old Linux distros
  • check_circleMitigating Logjam (CVE-2015-4000) by upgrading to 2048+ bits
  • check_circleStandardising dhparam files across a fleet via Ansible / Chef / Puppet templates
  • check_circleSetting up DHE-only fallback for clients that lack ECDHE support
  • check_circleGenerating one shared dhparam.pem to reuse across every vhost on every server
  • check_circlePre-generating dhparam during base AMI / Docker image build (move from runtime to build time)

DH vs ECDH — which does TLS use?

Modern TLS overwhelmingly uses ECDHE (Elliptic Curve Diffie-Hellman Ephemeral) over the curves X25519, P-256, and P-384 — these are faster, smaller, and stronger per bit than classical DH. Custom dhparam.pem only matters when a TLS 1.2 client cannot negotiate ECDHE (rare in 2026 — basically just legacy Java 6, Windows XP, Android 2.x). Even so, including a 2048+ bit dhparam is the responsible default; SSL Labs warns about its absence and downgrades the grade. TLS 1.3 drops custom DH entirely and uses only the fixed FFDHE / ECDHE groups defined in RFC 7919 / RFC 8446 — so dhparam.pem is unused on a TLS 1.3-only deployment.

security

Generated locally, runs locally

We generate the command — you run it locally so the private key never leaves your server. (DH parameters are not secret — they ride on every TLS handshake — but consistency matters: nothing about your config leaves the browser. Verify in DevTools Network: zero requests when you switch bit size.)

Finish your TLS deployment

Pair dhparam with a hardened nginx/Apache config and a properly issued certificate — all browser-side.

Frequently Asked Questions

What are DH parameters?

DH parameters are the prime number p and generator g used by the Diffie-Hellman key exchange algorithm. In TLS, the DHE (Diffie-Hellman Ephemeral) cipher suites use a fresh shared secret per session, providing forward secrecy. The server picks p and g once at startup; clients then use them for the math. Larger primes are stronger but slower — 2048 bits is the modern minimum, 1024 was broken by Logjam in 2015.

Why does dhparam take so long?

OpenSSL dhparam picks a random number of the requested bit length and then runs Miller-Rabin primality tests until it finds a safe prime (a prime p where (p-1)/2 is also prime). Safe primes are rare, so most candidates are rejected. 4096-bit safe primes can take 30+ minutes on a slow VM. Tip: add the -dsaparam flag — it generates DSA-style parameters which are cryptographically equivalent for DH but ~10x faster, per RFC 7919 Appendix A.

Do I need DH parameters for TLS 1.3?

No. TLS 1.3 removed all custom-DH cipher suites and uses only fixed, well-known FFDHE/ECDHE groups defined in RFC 7919 and RFC 8446 — clients and servers negotiate one of those groups, no per-server parameter file required. dhparam.pem is only consulted when a client negotiates a TLS 1.2 DHE-* cipher suite. If your config is TLS 1.3 only (Mozilla Modern profile), you can skip dhparam entirely.

Is 2048 bits enough?

Yes. NIST SP 800-57 rates 2048-bit DH as adequate through at least 2030. The Logjam attack broke 512- and 1024-bit primes by precomputing the discrete log against the most popular shared primes — at 2048 bits the precomputation cost is far beyond any known attacker. Mozilla, Cloudflare, and the Web Hosting Initiative all recommend 2048. Choose 3072 or 4096 only if you have a specific compliance requirement (FIPS 186-5 strict).

Where do I put the dhparam.pem file?

Anywhere readable by the web server process — /etc/ssl/dhparam.pem and /etc/nginx/dhparam.pem are the conventional locations. nginx: add ssl_dhparam /etc/ssl/dhparam.pem; inside the server { } block. Apache 2.4.7+: append the dhparam to the certificate file, or use SSLOpenSSLConfCmd DHParameters "/etc/ssl/dhparam.pem". Reload the server after deploying.

Can I share dhparam.pem between sites?

Yes, and you should — there is no security benefit to a unique dhparam per site (the security comes from the size of p, not its uniqueness). One dhparam.pem can be referenced by every vhost on every server. The file is not a secret either; it is sent to every TLS client on every handshake. This is the opposite of your private key file.

Do I need to regenerate dhparam periodically?

No. DH parameters do not have an expiry. The recommendation to "rotate dhparam" was based on outdated 1024-bit primes that were close to being attackable. A 2048-bit dhparam generated today is safe for a decade-plus. Generate once, deploy everywhere, forget about it. The only reason to regenerate is if you upgrade to a larger bit size.

What is the Logjam attack?

Logjam (May 2015) is a man-in-the-middle attack against TLS that downgrades a connection to 512-bit DHE_EXPORT cipher suites, then breaks the resulting weak DH using precomputed tables for the small set of well-known 512-bit primes shared by most servers. Mitigations: disable DHE_EXPORT (any modern TLS config does), use unique 2048+ bit dhparams, and prefer ECDHE (which is unaffected). Generating a 2048-bit dhparam with this tool is sufficient.

DH Parameters Generator — OpenSSL DHParam Command