Compact JWS vs JWE: Decode Is Not Verify
A JWT (RFC 7519, May 2015) is a claims set used as a JWS payload or as JWE plaintext. An optional leading Bearer prefix is stripped. Compact JWS (RFC 7515) is three base64url segments: header.payload.signature. Compact JWE (RFC 7516 §9) is five. Decoding a compact JWS on the live decoder writes header {"alg":"HS256","typ":"JWT"} and Ada Lovelace (sub user-42, iat 1516239022 → 2018-01-18T01:30:22.000Z, exp 1516242622 → 2018-01-18T02:30:22.000Z). Those NumericDate seconds are the same POSIX-seconds clock as /unix-timestamp/ Seconds mode. This guide does not convert 1700000000. The third segment is shown as bm90LWEtcmVhbC1zaWduYXR1cmU. Decode is not HMAC, RSA, ECDSA, or JWKS. Unsecured JWS uses alg none and a trailing dot. Encoding ASCII >>>??? writes Pj4-Pz8_ on /base64url/. Decoding Pj4-Pz8_ writes >>>???. Encoding NFC é writes w6k on /base64url/ and w6k= on /base64/. Encoding NFD e + U+0301 writes ZcyB on both. Compact JWS segments are not those outputs. Compose e + U+0301 to é (U+00E9) on /unicode-normalize/. Nothing is uploaded.
“JWT” does not tell you whether the claims are readable. RFC 7519 puts the same JSON object in a JWS (signed or MACed) or a JWE (encrypted). The live JWT decoder counts compact segments first, then base64url-decodes only a three-part JWS. This page names that fork. RFC 4648 §5 output >>>??? → Pj4-Pz8_ is /base64url/, not a compact JWS.
Three periods-of-two vs four
Compact JWS: header.payload.signature
RFC 7515 Compact Serialization is BASE64URL(UTF8(JWS Protected Header)) || '.' || BASE64URL(JWS Payload) || '.' || BASE64URL(JWS Signature) — exactly two period characters. The alphabet is RFC 4648 §5 (A-Z a-z 0-9 - _). Optional = padding is accepted here. That alphabet output on /base64url/ is >>>??? → Pj4-Pz8_, not a three-segment JWT. Try it with a compact HS256-shaped JWT. Decode writes header {"alg":"HS256","typ":"JWT"} and payload sub user-42, name Ada Lovelace, iat 1516239022, exp 1516242622. The third segment is shown as bm90LWEtcmVhbC1zaWduYXR1cmU (ASCII not-a-real-signature) — not an HMAC over the first two parts.
Compact JWE: five segments, claims stay ciphertext
RFC 7516 §9: JWEs have five base64url segments separated by four periods — JWE Protected Header, Encrypted Key, Initialization Vector, Ciphertext, Authentication Tag. Direct encryption (alg dir) still uses five parts; the encrypted-key segment may be empty. Appendix A.1's protected header encodes as eyJhbGciOiJSU0EtT0FFUCIsImVuYyI6IkEyNTZHQ00ifQ → {"alg":"RSA-OAEP","enc":"A256GCM"}. That first segment is readable JOSE, not the claims. Five segments are rejected here before any decrypt. Nested JWT (a JWS inside a JWE, or the reverse) is not unwrapped.
Decode is not verify
Header and payload are encoding, not a secret
After an optional leading Bearer prefix is stripped and whitespace is removed, Decode (a button, not as-you-type) splits on .. Header and payload become bytes via base64url, then UTF-8 with new TextDecoder('utf-8', { fatal: true }), then JSON.parse. Pretty-print is JSON.stringify(..., null, 2). Both must be JSON objects — an array or a primitive fails. The third segment is shown as the original base64url text. RFC 7515 validation (HMAC-SHA-256, RSASSA, ECDSA, or JWKS) never runs. alg is printed from the header, not checked against a key.
alg none still has three segments
RFC 7515 Appendix A.5 / RFC 7519 §6: an Unsecured JWS/JWT uses {"alg":"none"} (eyJhbGciOiJub25lIn0) and an empty signature, so the compact form ends with a period. RFC 7518 §3.6: recipients MUST verify that the signature octets are empty, and implementations MUST NOT accept Unsecured JWSs by default. This page still requires the trailing dot (two segments are rejected) and still does not treat that object as valid.
NumericDate is display only
iat / exp / nbf are Unix seconds, not a verdict
RFC 7519 NumericDate is a JSON number of seconds since 1970-01-01T00:00:00Z, leap seconds ignored (IEEE Std 1003.1; each day is 86400 of those seconds). When iat, exp, or nbf is a finite number, the decoder shows new Date(n * 1000).toISOString(). The sample exp 1516242622 is 2018-01-18T02:30:22.000Z. That UTC string is not compared to the clock. A past exp does not make the token “invalid” here. RFC 7515 Appendix A.5's exp 1300819380 is 2011-03-22T18:43:00.000Z. Seconds mode on /unix-timestamp/ is that same POSIX-seconds clock. This guide does not convert 1700000000.
Not a validator, not encryption
Copy writes the pretty-printed header and payload. This is not HMAC verify, not RS256/ES256, not JWKS, not a secret box, not alg allow-listing, not JWE decrypt, and not a Nested JWT unwrap. RFC 7516 JSON Serialization (ciphertext member) and JWS JSON Serialization (payload member) are out of scope. RFC 4648 §5 output >>>??? → Pj4-Pz8_ is /base64url/, not this decoder.
RFC 4648 §5 output is not a compact JWS
>>>??? → Pj4-Pz8_ on /base64url/
Compact JWS header and payload are RFC 4648 §5 base64url of UTF-8 JSON. That is not the encoded text on /base64url/. The sample there fills >>>???; clicking Encode writes Pj4-Pz8_ as encoded.txt. The same UTF-8 bytes on /base64/ are Pj4+Pz8/. Decode of Pj4-Pz8_ writes >>>??? as decoded.txt. Decode also accepts optional = padding (RFC 4648 §3.2). RFC 4648 §10 foobar is Zm9vYmFy (same on /base64/). Encode there does not call String.prototype.normalize. Base64url output of NFC é is w6k. Base64url output of NFD e + U+0301 is ZcyB. The same UTF-8 bytes on /base64/ are w6k= and ZcyB. NFC normalization e + U+0301 → é (U+00E9) as normalized.txt is /unicode-normalize/. /base64url/ does not split header.payload.signature or verify HMAC/RSA. Compact JWS output on /jwt-decoder/ stays the HS256 Ada Lovelace sample.
Inspect a compact JWS in the browser
Three segments only. The signature is shown, never verified. Nothing is uploaded.
Use JWT Decoder →FAQ
- What is the difference between JWS and JWE?
- JWS (JSON Web Signature) signs data for integrity. JWE (JSON Web Encryption) encrypts data for confidentiality.
- What do JWTs use?
- Most JWTs are compact JWS tokens with three base64url-encoded segments: header.payload.signature.
- Are JWT payloads encrypted?
- Only when the JWT is compact JWE (five base64url segments per RFC 7516). Compact JWS (three segments) only encodes the claims, so anyone can read the payload. This article does not decrypt JWE, and neither does /jwt-decoder/.
- Does this tool verify JWT signatures?
- No. This article compares compact JWS and JWE. It does not decode tokens. Decode a compact JWS in the browser with the live JWT decoder at /jwt-decoder/, which splits three base64url segments, shows header and payload JSON, and never verifies HMAC, RSA, or ECDSA. An optional Bearer prefix is stripped. JWE (five segments) is not decrypted. Nothing is uploaded.