Watch a key exchange, and find the handshake with no forward secrecy
Task
Run a TLS server and client against each other on your own lab VM and read what they negotiate: the protocol version, the cipher, and whether an ephemeral key exchange took place. Then force a handshake that uses RSA key transport instead and see the forward secrecy disappear, try a deprecated protocol and see it refused, and measure what a longer RSA key costs.
Steps
- Make a working directory and a throwaway certificate:
openssl req -x509 -newkey rsa:2048 -nodes -keyout tls.key -out tls.crt -subj '/CN=lab.internal' -days 7. - Start a TLS server on loopback only, in the background:
openssl s_server -accept 127.0.0.1:8443 -cert tls.crt -key tls.key -www >/tmp/s_server.log 2>&1 &. - Connect with TLS 1.3 and keep the lines that matter:
openssl s_client -connect 127.0.0.1:8443 -tls1_3 </dev/null 2>/dev/null | grep -E '^New|Temp Key|group'. Record the protocol, the cipher and the key exchange group. A newer OpenSSL may show a hybrid group such as X25519MLKEM768 -- a classical and a post-quantum exchange combined. - Force TLS 1.2 with an ephemeral elliptic-curve exchange: add
-tls1_2 -cipher ECDHE-RSA-AES256-GCM-SHA384to the same command. AServer Temp Keyline appears: that key was made for this session and thrown away, which is forward secrecy. - Force TLS 1.2 with RSA key transport:
-tls1_2 -cipher AES256-GCM-SHA384. TheServer Temp Keyline is gone. The session key was sent wrapped in the server's long-term RSA key, so anyone who recorded this session and later stealstls.keycan read it. - Ask for a deprecated protocol:
-tls1_1instead of-tls1_2. Current OpenSSL refuses it at its default security level, so the handshake fails rather than quietly downgrading. - Measure key length as a cost:
openssl speed -seconds 2 rsa2048 rsa4096 2>/dev/null | tail -2, and note how many signatures a second each size manages. - Write
/tmp/kex.md: one row per handshake with protocol, cipher, whether a temporary key appeared, and whether it is forward-secret; then one line on the RSA speed difference and why constrained devices prefer elliptic curves.
Verify
openssl s_client -connect 127.0.0.1:8443 -tls1_3 </dev/null 2>/dev/null | grep -cE 'Server Temp Key|Negotiated TLS1.3 group'
openssl s_client -connect 127.0.0.1:8443 -tls1_2 -cipher ECDHE-RSA-AES256-GCM-SHA384 </dev/null 2>/dev/null | grep -c 'Server Temp Key'
openssl s_client -connect 127.0.0.1:8443 -tls1_2 -cipher AES256-GCM-SHA384 </dev/null 2>/dev/null | grep -c 'Server Temp Key'
openssl s_client -connect 127.0.0.1:8443 -tls1_1 </dev/null 2>&1 | grep -c -e 'Cipher is (NONE)' -e 'no protocols available' -e 'alert'
grep -ciE 'forward' /tmp/kex.md
Run these while the server from step 2 is still running. The first two must be at least 1: both of those handshakes used an ephemeral exchange. The third must be 0: RSA key transport creates no temporary key, so it has no forward secrecy. If your OpenSSL build refuses that cipher suite outright, the third also prints 0 -- the refusal is the same lesson from the other side, so record it in kex.md. The fourth must be at least 1: the TLS 1.1 handshake failed. The fifth must be non-zero; your notes say which sessions were forward-secret.
Notes
Stop the server afterwards with kill %1, or pkill -f 's_server -accept 127.0.0.1:8443' if you have closed that shell. The third handshake is the one to remember: it was encrypted with a strong cipher and would look fine in any report that only lists cipher names. What it lacked was the property that protects recordings, which is why TLS 1.3 removed RSA key transport entirely.
This is an independent study companion for CompTIA Security+ SY0-801 and is not produced by or endorsed by CompTIA.