Demonstrating Diffie-Hellman Key Exchange with OpenSSL
The Diffie-Hellman key exchange algorithm is widely used in HTTPS to securely establish a shared secret between a client and server, even over an insecure channel. In this post, we’ll use openssl s_client
to connect to a real-world HTTPS server and examine how ECDHE (ephemeral elliptic curve Diffie-Hellman) is used.
What You Need
- A Linux/macOS system (or WSL on Windows)
- OpenSSL installed (openssl version to check)
- Internet access
Step-by-Step: Connect to a TLS Server with OpenSSL
Let’s connect to www.baidu.com
using OpenSSL and observe the handshake:
Step 1: Run OpenSSL Client
openssl s_client -connect www.baidu.com:443 -cipher ECDHE
This tells OpenSSL to:
- Connect to www.baidu.com on port 443 (HTTPS)
- Restrict cipher suites to only those using ECDHE
Step 2: Understand the Output
Here’s an example excerpt of what you might see:
CONNECTED(00000006)
depth=2 OU = GlobalSign Root CA - R3, O = GlobalSign, CN = GlobalSign
verify return:1
depth=1 C = BE, O = GlobalSign nv-sa, CN = GlobalSign RSA OV SSL CA 2018
verify return:1
depth=0 C = CN, ST = beijing, L = beijing, O = "Beijing Baidu Netcom Science Technology Co., Ltd", CN = baidu.com
verify return:1
---
Certificate chain
...
---
Server certificate
-----BEGIN CERTIFICATE-----
...
-----END CERTIFICATE-----
subject=C = CN, ST = beijing, L = beijing, O = "Beijing Baidu Netcom Science Technology Co., Ltd", CN = baidu.com
issuer=C = BE, O = GlobalSign nv-sa, CN = GlobalSign RSA OV SSL CA 2018
---
No client certificate CA names sent
Peer signing digest: SHA256
Peer signature type: RSA-PSS
Server Temp Key: ECDH, prime256v1, 256 bits
---
SSL handshake has read 5414 bytes and written 443 bytes
Verification: OK
---
New, TLSv1.2, Cipher is ECDHE-RSA-AES128-GCM-SHA256
Server public key is 2048 bit
Secure Renegotiation IS supported
Compression: NONE
Expansion: NONE
No ALPN negotiated
SSL-Session:
Protocol : TLSv1.2
Cipher : ECDHE-RSA-AES128-GCM-SHA256
Session-ID: BDB5233DDD9D825F7B817344531488F47A5698EC0BF4B1B8C33E042E228BB7D7
Session-ID-ctx:
Master-Key: 02B49C3C3658647AA95C2E0E19A3E7458E725306441C93A63A6628838F1C5409E48D5D23B76452153573FB6D32DFA360
PSK identity: None
PSK identity hint: None
SRP username: None
TLS session ticket:
0000 - cc 95 13 98 05 87 6f 12-cd de d9 e9 cc e0 cc f7 ......o.........
0010 - 0c 2b 50 7c 40 bd b2 24-cf a4 c0 4b 42 4b ff c9 .+P|@..$...KBK..
0020 - 7f 16 84 a5 bb f8 4b 40-37 5b 7e 6c 6e 06 64 8f ......K@7[~ln.d.
0030 - a0 4a 7a c0 55 9d c9 1d-69 b4 82 bb 5f 9e 97 7d .Jz.U...i..._..}
0040 - 78 f6 e6 ac 46 15 a3 53-f6 d8 f4 8e da 58 69 12 x...F..S.....Xi.
0050 - 44 7b b2 4e 42 ff 2c 71-07 2c 08 80 2f 0d e7 d3 D{.NB.,q.,../...
0060 - 49 2a ad 05 33 71 d8 be-da de 67 86 dd 01 00 1f I*..3q....g.....
0070 - 7e 1f 45 1c 78 0b bb 1a-6f 42 dc 4a 14 57 bd 12 ~.E.x...oB.J.W..
0080 - f7 38 8c 5b ff cd 88 0a-97 e6 4d ad f8 c7 83 d1 .8.[......M.....
0090 - 05 b6 88 31 81 47 e1 9f-c2 8f e9 28 cf d1 43 eb ...1.G.....(..C.
Start Time: 1747110246
Timeout : 7200 (sec)
Verify return code: 0 (ok)
Extended master secret: no
---
closed
Key Elements to Note
Field | Meaning |
---|---|
Cipher: ECDHE-RSA-AES128-GCM-SHA256 | Secures the handshake with ephemeral Diffie-Hellman key exchange and RSA authentication; Encrypts data using AES-128 in GCM mode. Ensures integrity using SHA-256. |
Server public key is 2048 bit | Refers to the RSA certificate (used for authentication) — not for key exchange |
Secure Renegotiation IS supported | Optional TLS feature |
Even though the RSA public key is shown, the session key is derived using ephemeral ECDH, which provides forward secrecy (past sessions can’t be decrypted even if RSA key is compromised later).
Want More Detail? Use -msg
To see the handshake messages themselves, run:
openssl s_client -connect www.baidu.com:443 -cipher ECDHE -msg
This shows handshake messages like:
>>> TLS 1.2 Handshake [ClientHello]
>>> TLS 1.2 Handshake [ServerHello]
>>> TLS 1.2 Handshake [ServerKeyExchange]
In ServerKeyExchange
, you’ll see the server’s ECDH public key, which will be used along with the client’s key to derive the shared secret.
Note: In TLS 1.3, the handshake is more streamlined and doesn’t use a separate
ServerKeyExchange
message; key exchange data is sent inServerHello
.
Summary
This simple demo shows how ECDHE (a form of Diffie-Hellman) is used in HTTPS via TLS to:
- Establish a shared secret
- Prevent passive eavesdropping
- Enable forward secrecy
This is done in every secure HTTPS connection you make in modern browsers.