TLS Record Parser
Paste TLS record-layer bytes as hex and decode the 5-byte record header (content type, version, length) and the handshake it carries. ClientHello and ServerHello are fully decoded: version, the 32-byte random, session id, cipher suites named by their IANA identifier, compression, and extensions — SNI server names, ALPN protocols, supported_versions, supported_groups, signature_algorithms, and key_share groups. Spaces, colons, dashes, dots, commas, and a 0x prefix are ignored. Runs in your browser; nothing is uploaded.
About this tool
TLS Record Parser decodes raw TLS record-layer bytes, given as a hex string, into the record header and — for handshake records — the handshake messages it carries.
Every TLS connection is framed as a series of records. Each record starts with a 5-byte header:
- Content Type —
change_cipher_spec(20),alert(21),handshake(22),application_data(23), orheartbeat(24). - Record Version — the record-layer protocol version (e.g.
TLS 1.0,TLS 1.2). Note that under TLS 1.3 the record version is kept at0x0303for compatibility; the real negotiated version lives in thesupported_versionsextension. - Length — the number of payload bytes that follow.
Handshake decoding
When the content type is handshake, the payload holds one or more handshake messages, each with a 1-byte type and a 3-byte length. ClientHello and ServerHello are fully decoded:
- Version — the legacy_version field.
- Random — the 32-byte client/server random.
- Session ID — the (legacy) session id.
- Cipher Suites — named by their IANA identifier, e.g.
TLS_AES_128_GCM_SHA256,TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256(a ClientHello lists the offered suites; a ServerHello reports the single selected one). - Compression Methods — usually just
null. - Extensions — including SNI server names (
server_name), ALPN protocols (e.g.h2,http/1.1), supported_versions, supported_groups (x25519,secp256r1, …), signature_algorithms, and key_share groups.
Alert records are decoded to their level (warning/fatal) and description
(e.g. handshake_failure, bad_certificate). application_data is encrypted,
so only the record header is shown.
TLS data on the wire is often several records back-to-back (for example a ServerHello record followed by a Certificate record). Paste the whole stream and each record is parsed and labelled in turn.
Where to get the bytes
A TLS record is the bytes on the wire after the TCP header. In Wireshark, expand
the TLSv1.x Record Layer and copy the bytes (right-click → Copy → …as a Hex
Stream), or take them from a tcpdump/openssl s_client capture. Input may use
spaces, colons, dashes, dots, commas, or a leading 0x; they are all ignored.
Common uses
- Decode a captured ClientHello to see the offered cipher suites, SNI host, and ALPN protocols without re-opening the capture.
- Confirm the selected cipher suite and TLS version from a ServerHello.
- Read a TLS alert to find out why a handshake failed.
FAQ
Why does a TLS 1.3 handshake show "TLS 1.2" in the header?
That's the protocol working as designed. TLS 1.3 keeps the record-layer version
and the hello's legacy_version pinned at 0x0303 (TLS 1.2) for middlebox
compatibility. The real negotiated version is carried in the
supported_versions extension — which this tool decodes, so check there for
TLS 1.3.
Can I paste several records at once?
Yes. Wire captures are usually multiple records back-to-back (say, a ServerHello record followed by a Certificate record). The parser walks the byte stream record by record and labels each one — paste the whole hex stream in one go.
What happens if my capture is cut off mid-record?
You still get a best-effort decode. The output reports both the declared payload length and how many bytes are actually present, and truncation or partially-decodable handshake messages are surfaced as notes instead of failing the whole parse — useful when a copy from Wireshark grabbed less than the full record.
Can it show me the plaintext inside application_data records?
No — application_data payloads are encrypted with the session keys, which a
parser can't recover from the bytes alone. For those records only the 5-byte
header (type, version, length) is meaningful. The unencrypted parts of the
handshake — hellos, alerts — are where all the decodable detail lives.
Developer & Automation Access
Run it from the terminal
Same engine as this page, headless — via the gizza CLI:
gizza tool parse-tls-record "16 03 01 ... (a handshake record begins with 16 03 0x)"New to the CLI? Get gizza →
Open it by URL
Pre-fill and auto-run this tool with query parameters — the names match the API/CLI:
https://gizza.ai/tools/parse-tls-record/?record=16%2003%2001%20...%20%28a%20handshake%20record%20begins%20with%2016%2003%200x%29Machine-readable descriptor: tool.json — title + parameters JSON Schema for agents.
