Using TLS 1.3 Pre‑Shared Keys for Faster Handshakes in OpenSSL 3.0
Learn how to enable TLS 1.3 pre‑shared keys in OpenSSL 3.0 to cut handshake latency, with a concrete command‑line example, verification steps, and a discussion of key‑management trade‑offs.
21 Sept 2026, 11:59 UTC

Problem: Handshake latency adds up in TLS‑protected services
Every new TLS connection requires a handshake. Even with TLS 1.3’s single round‑trip design, the client and server still exchange cryptographic material before application data can flow. In high‑frequency or latency‑sensitive workloads (e.g., API gateways, micro‑service meshes), that extra round‑trip can become a noticeable bottleneck.
Thesis: TLS 1.3 pre‑shared keys (PSK) let you skip most of the handshake
When both sides already possess a shared secret, TLS 1.3 can resume a session in zero‑round‑trip time (0‑RTT) or a single round‑trip, depending on the mode. OpenSSL 3.0 exposes this capability through the -psk and -psk_identity options of the s_server and s_client utilities, letting you test PSK‑based resumption without writing code.
How TLS 1.3 PSK works (concept)
In a PSK handshake the client sends its chosen identity in the ClientHello. The server looks up the corresponding secret, derives the traffic keys, and replies with a ServerHello that indicates the PSK was selected. Because the secret is already known, the key‑exchange steps (Diffie‑Hellman) can be omitted, reducing the number of cryptographic operations.
Configuring an OpenSSL 3.0 server for PSK
Start a test server that advertises TLS 1.3 only and expects a specific PSK. The command must be run in a terminal where you have permission to bind to the chosen port (typically >1024 to avoid needing root).
# Replace 8443 with any free port; replace 1234 with your secret (hex string).
openssl s_server -accept 8443 -tls1_3 -psk 1234 -psk_identity myid
Required permissions: ability to open a listening socket on the chosen port. No special privileges are needed for the PSK itself, but note that the secret appears in the command line and may be visible to other users on the same host via ps. For production, consider loading the secret from an environment variable or a secure vault and using a callback instead of the command‑line flag.
Client side: presenting the PSK identity
On the client machine, run s_client with the same PSK and identity. Use the -debug flag to see the handshake messages and verify that the PSK extension is exchanged.
# Connect to the server started above; adjust host and port as needed.
openssl s_client -connect localhost:8443 -tls1_3 -psk 1234 -psk_identity myid -debug
What to look for in the debug output:
- A line containing "Pre-Shared Key Identity Extension" with the value
myid. - No "Key Share" entry (the server omitted the Diffie‑Hellman exchange because the PSK was used).
- The handshake finishes with "Finished" messages from both sides.
If you see those items, the connection resumed using the PSK.
Trade‑off and limitation: key management and backward compatibility
While PSK reduces handshake cost, it introduces operational considerations:
- Secret distribution: Both client and server must possess the same PSK ahead of time. Securely provisioning and rotating these secrets can be more complex than relying on certificate‑based authentication.
- Exposure risk: Passing the PSK on the command line (as in the test example) may expose it in process lists or shell history. In production, avoid command‑line secrets; use a thread‑safe
psk_server_callbackthat retrieves the key from a protected store. - Compatibility: Enabling
-tls1_3disables older cipher suites by default. Clients that only support TLS 1.2 or earlier will fail to connect unless you explicitly allow fallback versions (e.g.,-tls1_2) or configure dual‑stack ports.
Practical way to verify the setup
After starting server and client as shown, you can confirm that a PSK‑based handshake occurred without needing to interpret the full debug trace:
# Run the client with -tlsextdebug to get a concise list of extensions.
openssl s_client -connect localhost:8443 -tls1_3 -psk 1234 -psk_identity myid -tlsextdebug 2>/dev/null | grep -i "pre-shared"
If the command prints a line containing the identity you supplied, the PSK extension was negotiated.
Actionable closing
To experiment with TLS 1.3 PSK resumption in your own environment:
- Verify you have OpenSSL 3.0 or newer:
openssl version. - Start a server on a non‑privileged port with
-tls1_3 -psk <hex‑secret> -psk_identity <id>. - Connect a client with the same
-pskand-psk_identityflags, adding-debugor-tlsextdebugto observe the handshake. - Check the output for the PSK identity line and the absence of a Key Share entry.
- When moving beyond testing, replace the command‑line secret with a secure callback, enforce strict access controls on the secret store, and consider keeping a TLS 1.2 fallback port for legacy clients.
By following these steps you can measure the latency improvement of PSK‑based resumption and decide whether the operational trade‑offs fit your service’s security and performance requirements.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.