Post-Quantum TLS Checker
How the post-quantum checker runs two TLS handshakes, how it classifies the key exchange group, what each finding means for recorded traffic, and how to turn on ML-KEM and confirm it.
The tool page is tamperbox.dev/post-quantum-checker. It opens by checking tamperbox.dev live and answers one narrow question: is the session key of a TLS connection to this host protected against a future quantum computer? This page is the long version: what the two handshakes do, how a group name is classified, every finding the page can show, and how to turn ML-KEM on and confirm it without Tamperbox.
What the tool answers
Section titled “What the tool answers”Three questions, in the order the result answers them:
- Which key exchange group does the server choose? The first handshake offers the probe’s default list, classical and hybrid groups together, and the server picks one. This decides the verdict.
- Can the server use ML-KEM at all? The second handshake offers only the three ML-KEM hybrids, so the server either completes it with one of them or refuses. This separates “not supported” from “supported but not preferred”.
- What does that protect? The session key, not the certificate. The result says whether a recording of the traffic could be decrypted later, and what to change on the server when it could.
The question is deliberately narrow. Certificate trust, names and expiry belong to the SSL Certificate Checker.
Inputs
Section titled “Inputs”A host name
Section titled “A host name”example.com or www.example.com. The check runs when you stop typing, or on Enter, and costs two connections from our server to port 443. A pasted address is reduced to its host by the shared paste cleanup: https://example.com/login becomes example.com, an email address becomes its domain, quotes and brackets are dropped. Text that fits none of these stays as pasted so the error can explain it.
A host name with a port
Section titled “A host name with a port”:443 is accepted and removed. Any other port is refused, because the probe speaks HTTPS only:
| Input | What happens |
|---|---|
example.com:443 |
Checked as example.com |
example.com:8443 |
Refused: “Only port 443 is checked”. Heal it offers Check port 443 |
mail.example.com:25, :465, :587, :993, :995 |
Refused with the openssl s_client command for that mail port, so you can paste its output instead |
Pasted handshake output
Section titled “Pasted handshake output”Anything that looks like a handshake, or any multi-line text, is read in the browser. The parser takes the protocol, the cipher, the group, ALPN, the verification code, a TLS alert and any PEM certificates. The group comes from Negotiated TLS1.3 group, Peer Temp Key or Server Temp Key in openssl s_client output, or from the third field of SSL connection using in curl -v. <NULL> counts as no group. If the paste includes the command line, -servername or -connect names the host and -groups names what was offered. Output with no protocol, group or alert is refused: “No TLS handshake found.”
A .txt file up to 128 KiB can be dropped or opened. It is read in the browser like a paste.
Reading the result
Section titled “Reading the result”Verdict and chips
Section titled “Verdict and chips”The verdict line names the outcome: Post-quantum secure, Not post-quantum secure, Post-quantum capable, Key exchange not recognised or No TLS handshake completed. The detail names the group and, for a live check, the host and the time of the check. Chips repeat the group, the TLS version, the ML-KEM-only result and the certificate’s classical key; each one scrolls to its evidence.
Findings
Section titled “Findings”One finding per question, worst first. Passes fold into one line, “n checks passed”, which opens on click. The finding reference lists every title.
History and Take it further
Section titled “History and Take it further”History logs each Break it load, with Revert for the newest change and Reset input to return to what you entered. Take it further carries derived values into the same category: the host with port 443 into the DANE checker, and, for pasted output, the host named in the command into the SSL Certificate Checker.
The key, the handshakes, what it protects
Section titled “The key, the handshakes, what it protects”The key the probe negotiated splits the group into its parts: a classical part and a post-quantum part, with an empty “Nothing” slot when there is no post-quantum part. Two handshakes shows each attempt: what was offered, what came back, and why. What it protects states whether traffic recorded today could be read later, the TLS version, and the certificate key. Turn on ML-KEM appears only when the server should change, with a configuration for nginx, Apache, Caddy, HAProxy or Go.
Browser transfers
Section titled “Browser transfers”Explicit tool links temporarily place the transferred input in browser sessionStorage. The URL fragment carries a random token, not the input. The receiving page accepts that token once, for its destination path and for less than one minute, then removes it from the address. A same-origin browser channel can complete a transfer into another tab. Ordinary documentation links do not transfer input. When browser storage is unavailable, navigation still works but the input may need to be pasted again.
Method
Section titled “Method”The rules live in assessPostQuantum and groupInfo in the page’s TLS library; the probe is openssl s_client on the Tamperbox server.
The two handshakes
Section titled “The two handshakes”| Handshake | Command options | Counts as success when |
|---|---|---|
| Default client | -servername host -verify_hostname host -showcerts -alpn h2,http/1.1 and OpenSSL’s default group list |
Any group is reported |
| ML-KEM only | The same, plus -tls1_3 -groups X25519MLKEM768:SecP256r1MLKEM768:SecP384r1MLKEM1024 |
TLS 1.3 completes, a certificate comes back and the group is one of the three |
Both run in parallel with a 12 second deadline. The ML-KEM-only result is reported as accepted or “Not shown”, never “not supported”: RFC 9846, Section 2.1 requires that “If no common cryptographic parameters can be negotiated, the server MUST abort the handshake with an appropriate alert”, but an abort has other causes too (a firewall, a TLS 1.2-only front end, a timeout), so a refusal is not proof.
Classifying a group
Section titled “Classifying a group”Each name is looked up, case-insensitively, in a fixed catalog:
| Kind | Names | Post-quantum |
|---|---|---|
| Hybrid | X25519MLKEM768, SecP256r1MLKEM768, SecP384r1MLKEM1024 | Yes |
| ML-KEM alone | MLKEM512, MLKEM768, MLKEM1024 | Yes |
| Obsolete draft | X25519Kyber768Draft00, X25519Kyber512Draft00 | No |
| Classical | X25519, X448, P-256 (also secp256r1, prime256v1), P-384, P-521, ffdhe2048, ffdhe3072, DH | No |
| Unknown | Anything else | Not claimed |
The hybrids are defined in RFC 10024, Section 7; the draft codepoints are marked obsolete by RFC 10024, Section 7.4. An unknown name is never guessed at.
Deciding the verdict
Section titled “Deciding the verdict”The first matching rule decides:
| Order | Condition | State | Verdict |
|---|---|---|---|
| 1 | Default group is hybrid or ML-KEM alone | secure |
Post-quantum secure |
| 2 | Default group is a Kyber draft | obsolete |
Not post-quantum secure |
| 3 | Protocol older than TLS 1.3 | tls12 |
Not post-quantum secure |
| 4 | Default group unknown | unknown-group |
Key exchange not recognised |
| 5 | Default group classical, ML-KEM-only accepted | prefers-classical |
Not post-quantum secure |
| 6 | Default group classical, ML-KEM-only not shown | classical |
Not post-quantum secure |
| 7 | No default group, ML-KEM-only accepted | secure-only |
Post-quantum capable |
| 8 | Neither gave a group | no-handshake |
No TLS handshake completed |
Rule 3 follows from RFC 9954, Section 3.1: hybrid groups are negotiated through the TLS 1.3 supported_groups and key_share extensions (RFC 9846, Section 4.3.7 and Section 4.3.8), which TLS 1.2 does not use for this purpose. A paste is one handshake, so only rules 1 to 4, 6 and 8 can apply to it.
Standards and conformance
Section titled “Standards and conformance”The tool observes; it is not a TLS implementation. OpenSSL on our server performs the handshakes, and the page judges the reported group.
RFC 9846: TLS 1.3
Section titled “RFC 9846: TLS 1.3”RFC 9846 is the current TLS 1.3 specification and obsoletes RFC 8446.
| Section | Rule | What the tool does |
|---|---|---|
| 2 | “the server’s share MUST be in the same group as one of the client’s shares” | Reports the group the server’s share used |
| 2.1 | No common parameters: abort with an alert | A refusal is shown as “Not shown”, and a pasted alert is named |
| 4.3.7 | Client lists supported groups | The ML-KEM-only handshake restricts the list to three hybrids |
| 4.3.8 | Key share per offered group | Not inspected byte by byte; only the negotiated group is read |
RFC 10024: ML-KEM hybrids in TLS 1.3
Section titled “RFC 10024: ML-KEM hybrids in TLS 1.3”RFC 10024, a Proposed Standard, defines the three hybrids the probe offers. Section 4.3 fixes the shared secret: “For X25519MLKEM768, the shared secret is the concatenation of the ML-KEM shared secret and the X25519 shared secret.” The tool names both parts but does not verify the concatenation; that is the TLS library’s job. Section 7.1 marks X25519MLKEM768 as Recommended, which is why the configuration puts it first.
RFC 9954 and FIPS 203
Section titled “RFC 9954 and FIPS 203”RFC 9954 (Informational) is the hybrid design the hybrids follow. Section 3.2 says the client’s shares are listed in preference order and “the server selects one algorithm”. That selection is what the default handshake observes, and why a server that supports ML-KEM can still pick X25519. FIPS 203 (August 2024) defines ML-KEM itself; the tool relies on it only for the names ML-KEM-768 and ML-KEM-1024.
Where the tool stops
Section titled “Where the tool stops”- Pure ML-KEM groups are classified, but the probe does not offer them: draft-ietf-tls-mlkem is still a draft.
- HelloRetryRequest is not reported separately; a server that asks for another share still ends with one group.
- Certificate signatures are classical everywhere today and are not judged.
- Group names are read as OpenSSL prints them; see the TLS Supported Groups registry for codepoints.
Finding reference
Section titled “Finding reference”Every finding id the page emits, grouped by the question it answers.
Key exchange group
Section titled “Key exchange group”| Title | Severity | Basis | Meaning | Fix |
|---|---|---|---|---|
| ML-KEM key exchange: group | PASS | RFC 10024, 7 | Recorded traffic stays protected | None |
| Classical key exchange: group | FAIL | RFC 9954, 3.2 | Recorded traffic can be decrypted later | Put X25519MLKEM768 first |
| Obsolete Kyber draft: group | FAIL | RFC 10024, 7.4 | Browsers no longer offer it and fall back to classical | Replace with X25519MLKEM768 |
| Key exchange not recognised: group | CHECK | Catalog | No claim either way | Look the name up in the registry |
| Default-client handshake gave no group | CHECK | RFC 9846, 2.1 | Ordinary clients’ result unknown | Check again |
| Handshake refused: alert | CHECK | RFC 9846, 2.1 | The offered groups had no match | Run without -groups |
| No key exchange reported | CHECK | Nothing to judge | Confirm HTTPS on 443 |
Protocol, preference and certificate
Section titled “Protocol, preference and certificate”| Title | Severity | Basis | Meaning | Fix |
|---|---|---|---|---|
| TLS 1.3 negotiated | PASS | RFC 9954, 3.1 | Hybrids are possible | None |
| TLS 1.2 cannot carry ML-KEM | FAIL | RFC 9954, 3.1 | No hybrid on this connection | Turn TLS 1.3 on |
| Prefers a classical group over hybrid | CHECK | RFC 9954, 3.2 | Support exists but is not chosen | Reorder the group list |
| Accepts hybrid when it is the only choice | PASS | RFC 10024, 4 | Support confirmed | None |
| ML-KEM-only handshake did not complete | INFO | RFC 9846, 2.1 | Not proof of no support | Read with the default result |
| Certificate signature stays classical | INFO | Signatures only need to hold during the handshake | None |
Classical key exchange
Section titled “Classical key exchange”- Find what terminates TLS: a CDN, a load balancer or the web server. Its settings decide the result.
- Upgrade the TLS library: OpenSSL 3.5 or later for nginx, Apache and HAProxy; Go 1.24 or later; Caddy 2.10 or later.
- Put the hybrid first. For nginx:
ssl_ecdh_curve X25519MLKEM768:X25519:prime256v1;. The tool shows the line for Apache (SSLOpenSSLConfCmd Curves), HAProxy (ssl-default-bind-curves), Caddy (curves) and Go (CurvePreferences). - Reload and confirm independently:
openssl s_client -connect example.com:443 -servername example.com -groups X25519MLKEM768 </dev/null 2>/dev/null | grep -E 'Negotiated TLS1.3 group|Protocol'An OpenSSL 3.5 client prints Negotiated TLS1.3 group: X25519MLKEM768 when the server accepts it.
Prefers a classical group
Section titled “Prefers a classical group”The server already has ML-KEM. An old group list puts X25519 first, so the server picks it whenever both are offered. Move X25519MLKEM768 to the front and check again. Run the command above without -groups to see the server’s choice against OpenSSL’s default offer.
TLS 1.2 or an obsolete draft
Section titled “TLS 1.2 or an obsolete draft”TLS 1.2 is usually an old ssl_protocols line or a load balancer security policy; enable TLS 1.3 first. A Kyber draft means a TLS library or proxy older than the standard; upgrade it and list X25519MLKEM768 instead.
Break it cases
Section titled “Break it cases”| Button | What it loads | Expected verdict |
|---|---|---|
| Classical X25519 | Your host, Peer Temp Key: X25519 |
Not post-quantum secure |
| Obsolete Kyber draft | Your host, X25519Kyber768Draft00 | Not post-quantum secure |
| TLS 1.2 only | Your host, TLS 1.2 and X25519 | Not post-quantum secure |
| P-256 hybrid | Your host, SecP256r1MLKEM768 | Post-quantum secure |
| Handshake refused | -groups X25519MLKEM768 and a handshake failure alert |
No connection |
Each case is built from your host and cipher and read locally; History restores your input. Heal it offers Check port 443 for a wrong port.
Worked example
Section titled “Worked example”The page opens on tamperbox.dev, checked live. Values change with the server’s configuration, so read this as a guide to the shape, not as fixed facts. Read the negotiated group and protocol from the current result, then compare the default handshake with the ML-KEM-only attempt. A hybrid result combines a classical group with ML-KEM; it does not make the certificate signature post-quantum. Findings explain missing support, preference or probe limitations, and configuration advice appears only when the result calls for it. Take it further offers the DANE check for tamperbox.dev:443.
To see the repair path, press Classical X25519. The input becomes an openssl s_client transcript for your host with Peer Temp Key: X25519; the verdict turns to Not post-quantum secure, the empty “Nothing” slot appears, and Turn on ML-KEM shows the line for your server. Revert brings the live result back.
For agents
Section titled “For agents”The Tamperbox MCP server exposes the same live check as post_quantum_checker, and post_quantum_analyze for pasted evidence. Search the catalog, inspect the schema and call it with the host name. Keep these warnings with any conclusion:
- Two connections from one location at one moment; a browser’s offer can differ from the probe’s.
supported: nullmeans “not shown”, never “not supported”.- Certificate signatures are not assessed.
See Connect an MCP client and Code mode.
Limits
Section titled “Limits”- Port 443 only, one location, one moment; other edges behind the same name can differ.
- The default handshake uses OpenSSL’s offer, not a browser ClientHello.
- A failed ML-KEM-only handshake does not prove lack of support.
- Pure ML-KEM groups are classified but not probed.
- Pasted output is reported as supplied.
- History is a browser interaction record, not server monitoring. Explicit tool links use temporary browser storage as described in Browser transfers.
References
Section titled “References”- RFC 9846, The Transport Layer Security (TLS) Protocol Version 1.3. Proposed Standard; obsoletes RFC 8446. Sections used: 2, 2.1, 4.3.7, 4.3.8.
- RFC 10024, Post-Quantum Traditional Hybrid Key Agreement Mechanisms for TLS 1.3. Proposed Standard, August 2026; obsoletes the Kyber draft codepoints. Sections used: 4, 4.3, 7, 7.1, 7.4.
- RFC 9954, Hybrid Key Exchange in TLS 1.3. Informational, July 2026. Sections used: 3.1, 3.2.
- FIPS 203, Module-Lattice-Based Key-Encapsulation Mechanism Standard. NIST, August 2024.
- draft-ietf-tls-mlkem, ML-KEM for TLS 1.3. Internet-Draft, not yet published; cited for the pure ML-KEM names.
- IANA TLS Supported Groups registry.