I'm the developer for a web application that was recently pen tested. One of the vulnerabilities reported from the pen test is that our server uses an unsafe Diffie-Hellman prime in our key exchange. I interpret this as unsafe, e.g. not a Safe prime. For additional context, the pen tester referenced this security advisory.

I would like to verify this finding. Specifically, I am seeking the "know-how" to classify the prime as safe or unsafe. This does not necessarily have to be from an intellectual perspective, a third party resource would be just fine. I tried using SSL labs, which checks if you used a common prime, but not if it's an unsafe prime.

How can I assess whether my site's Diffie Hellman prime is safe or unsafe?

  • Are you using some known crypto library for Diffie-Hellman? I assume they referred to some published weakness in the implementation. Beside that there are some recommendations for choosing safe prime numbers. For instance, this answer might help: security.stackexchange.com/a/5264/18241 Mar 19, 2019 at 21:24

2 Answers 2


openssl dhparam has a -check argument you can use. But the current version of openssl is incorrect and is too strict. As evidence, the DHE groups from RFC 7919 which are the only groups you can use for DHE with TLS 1.3 do not pass this check, even though they are safe to use.

The "unsafe" group params are those generated by openssl dhparam -dsaparam. They are supposedly actually safe to use as long as your TLS server has SSL_OP_SINGLE_DH_USE set (as the security advisory you linked says). With OpenSSL 1.1.1, this option is always on and does nothing (compare the manual for 1.1.0 and 1.1.1).

You can read the code invoked when you run dhparam, dhparam -dsaparam and dhparam -check. Just don't ask me to explain why the code does what it does.

On Security Stack Exchange, people can read man pages and browse code on Github, but not necessarily really understand the math. If you want someone to explain the math to you, you should ask on Cryptography Stack Exchange. But here is an answer that might be enough to satisfy you.

What you should do: either replace the DH group your webserver uses with one generated by openssl dhparam 2048 or use the values from RFC 7919.

To answer the question "how did the pentester know?", the pentester likely ran something like this:

set -e
rm -f dh.pcapng
sudo tcpdump -w dh.pcapng &
sleep 2
echo "Q" | openssl s_client -cipher 'EDH' -servername $1 -connect $1:443
sleep 2
sudo killall tcpdump
sleep 2
printf "asn1=SEQUENCE:seq_sect\n[seq_sect]\nfield1=INTEGER:0x" >dh.cnf
tshark -r dh.pcapng -2 -R ssl.handshake.p -T fields -e ssl.handshake.p | sed -e 's/://g' >>dh.cnf
printf "\nfield2=INTEGER:0x" >>dh.cnf
tshark -r dh.pcapng -2 -R ssl.handshake.g -T fields -e ssl.handshake.g | sed -e 's/://g' >>dh.cnf
openssl asn1parse -genconf dh.cnf -noout -out dh.der
openssl dhparam -check -noout -inform DER -in dh.der

with a domain name as argument (put that into a file called dh.sh, then run bash dh.sh www.example.com with your domain).

  • People can do some more things here than reading man pages and github pages. But the folks at Cryptography are definitely better at math. That is for sure. ;)
    – Tom K.
    Mar 25, 2019 at 13:14
  • It'd probably be better to generate them yourself than use the rigid ones to avoid precomputation attacks that may become possible in the future.
    – forest
    Mar 26, 2019 at 4:04


NMAP has a script that can help here, it is from their website: https://nmap.org/nsedoc/scripts/ssl-dh-params.html

Diffie-Hellman MODP group parameters are extracted and analyzed for vulnerability to Logjam (CVE 2015-4000) and other weaknesses.

The direct download is here: https://svn.nmap.org/nmap/scripts/ssl-dh-params.nse

The script can be run from the same directory where the .nse file is saved, run it without adding the .nse extension

nmap --script ssl-dh-params <target ip/fqdn>


With OpenSSL, you can also extract the key, use on of the following commands:

openssl s_client -cipher 'DHE' -tls1_2 -msg -connect {server:port}

This will show the bare ServerKeyExchange, and the key starts in the 7th hex block.

To get the full data, use -trace instead of -msg this will show the ServerKeyExchange, with the certificate in the dh_p part.

You still need to lookup the prime numbers manually here, but probably someone can create a script for this.

  • The nmap script didn't always work for me, it showed no wrong key even though the openssl showed the common key (e.g. AD107E1E...) Jun 9, 2023 at 8:58

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .