Inspect and Convert OpenSSL TLS Session Files with sess_id
You will finish with a repeatable way to inspect an OpenSSL SSL/TLS session file, convert it between PEM and DER, and produce NSS keylog-format output when a debugging tool needs it. The examples use OpenSSL 3.6.1 on this machine. The packaged Ubuntu version is 3.0.13, so check the binary you are actually invoking before depending on version-specific fields.
The route
Jump straight to the step you need, or tick off Done means at the end.
Allow about fifteen minutes. You need the openssl command and a session file produced by a test client such as openssl s_client -sess_out. The workflow reads and rewrites session data only. It does not establish a production connection, change a server, or alter certificate configuration.
1. Check the binary and its options
Start with ordinary, unprivileged checks. They confirm both the version and the command syntax installed on your PATH:
$ command -v openssl
/home/linuxbrew/.linuxbrew/bin/openssl
$ openssl version
OpenSSL 3.6.1 27 Jan 2026
$ openssl sess_id -help
Usage: sess_id [options]
General options:
-help Display this summary
-context val Set the session ID context
Input options:
-in val Input file - default stdin
-inform PEM|DER Input format - default PEM (DER or PEM)
Output options:
-out outfile Output file - default stdout
-outform format Output format - default PEM (PEM, DER or NSS)
-text Print ssl session id details
-cert Output certificate
-noout Don't output the encoded session info
The subcommand reads standard input when -in is omitted and writes standard output when -out is omitted. PEM is the default for both directions. Treat those defaults as a pipeline choice, not as a guarantee that a terminal is a suitable destination: session output can contain secret key material.
Checkpoint: if command -v resolves a different installation, run that binary's version and sess_id -help again. Do not mix an example's output with assumptions about another OpenSSL build.
2. Obtain a session file without using a production key
The usual input is a file saved by a test connection. For a local test server, create a temporary certificate and keep every file under a temporary directory:
$ work=$(mktemp -d /tmp/openssl-sess-id.XXXXXX)
$ openssl req -x509 -newkey rsa:2048 -nodes \
-keyout "$work/key.pem" -out "$work/cert.pem" \
-subj /CN=localhost -days 1
$ openssl s_server -quiet -accept 18443 \
-cert "$work/cert.pem" -key "$work/key.pem" -www &
$ server_pid=$!
$ printf 'GET / HTTP/1.0\n\n' | openssl s_client \
-connect 127.0.0.1:18443 -servername localhost \
-sess_out "$work/session.pem" -quiet
$ kill "$server_pid"
$ test -s "$work/session.pem" && echo 'session saved'
This local server is only a fixture. A real s_client connection needs the server's certificate policy and, often, an explicit trust decision. Do not copy a private production key into a temporary test directory merely to generate a session file.
Checkpoint: inspect the file header before parsing it:
$ head -n 1 "$work/session.pem"
-----BEGIN SSL SESSION PARAMETERS-----
The session file is sensitive. The encoded session can include a TLS resumption secret or equivalent key material. Restrict access, avoid attaching it to tickets or committing it to source control, and remove it when the debugging task is complete. Removal is irreversible, so confirm the exact temporary path first.
3. Print the session details without the encoded block
Use -text -noout for a readable diagnostic. This avoids repeating the PEM representation in the terminal:
$ openssl sess_id -in "$work/session.pem" -text -noout
SSL-Session:
Protocol : TLSv1.3
Cipher : TLS_AES_256_GCM_SHA384
Session-ID: E3552CE047482044C79479EFD30A0BA457BBBC983F4DEA9FB963F627158FBCDB
Session-ID-ctx:
Resumption PSK: 6549C1127B9B1E00B8FC2431D8A900234DAA4079E3ED9670AF80E829603D9541CD779328B12FDF9DD3F35343AE1D5A06
PSK identity: None
PSK identity hint: None
Your identifiers and ticket values will differ. The useful checks are the protocol, cipher and session identifier, not a byte-for-byte match with this output. OpenSSL 3.0 and 3.6 can expose different TLS 1.3 fields because the encoded structure is not a stable interchange format.
-noout suppresses the encoded session. Without it, -text prints details and then writes the encoded representation in the selected output format. Use -cert when the session contains a certificate and you need that certificate emitted; combine it with -text if you also want certificate details in text form.
4. Convert PEM to DER and verify the round trip
Choose a new destination, then convert explicitly. The command below does not change the source file:
$ openssl sess_id -in "$work/session.pem" \
-inform PEM -out "$work/session.der" -outform DER
$ test -s "$work/session.der" && echo 'DER session saved'
DER session saved
$ openssl sess_id -in "$work/session.der" \
-inform DER -text -noout | sed -n '1,6p'
SSL-Session:
Protocol : TLSv1.3
Cipher : TLS_AES_256_GCM_SHA384
Be explicit about both formats in scripts. If you redirect output with >, the shell truncates an existing destination before sess_id has parsed the input. Write to a new filename and replace an old artefact only after the command and a verification check have succeeded.
5. Produce NSS keylog output only for controlled debugging
The NSS output format reports the session ID and master or resumption key in the keylog style expected by some debugging tools:
$ openssl sess_id -in "$work/session.pem" \
-out "$work/session.keylog" -outform NSS -noout
$ test -s "$work/session.keylog" && echo 'NSS output saved'
NSS output saved
Do not treat this as an ordinary log file. Anyone who obtains usable session secrets may be able to decrypt captured traffic, depending on the protocol and capture context. Keep the output on an access-controlled debugging host, do not send it to a shared log collector, and destroy it after analysis. There is no undo operation for a copy that has already been disclosed, so prevent that disclosure at the source.
6. Diagnose input and option mistakes
A format mismatch normally means that the input flag is wrong, not that the session is corrupt. Check the first line and retry with the matching -inform value:
$ openssl sess_id -in "$work/session.der" -inform PEM -text -noout
Error reading SSL session
$ openssl sess_id -in "$work/session.der" -inform DER -text -noout
SSL-Session:
Exact diagnostic wording can vary between OpenSSL releases. An empty file, a truncated PEM block, or a session generated by an incompatible OpenSSL version can also fail to parse. Preserve the original capture while investigating and compare its header and size before changing anything.
-context ID sets the session ID context used in the output and accepts any string. It is an unusual diagnostic option, not a way to repair a failed handshake. Do not add it to a conversion script unless the consumer specifically requires a changed context.
Done means
- You confirmed the OpenSSL binary and version being used.
- You inspected the session with
-text -nooutwithout needlessly printing encoded secrets. - You matched
-informand-outformto the actual files. - You verified a DER conversion by parsing the new file.
- You used NSS output only in a controlled debugging workflow.
- Temporary session files and keylog output are access-controlled and scheduled for secure removal.