PS512: RSASSA-PSS with SHA-512 in a JWT
PS512 is RSA-PSS with SHA-512 throughout and a 64 byte salt. It is the largest PSS variant, and the only one where the padding is big enough that the key size stops being a formality.
At a glance
- Algorithm
- PS512, RSASSA-PSS using SHA-512 and MGF1 with SHA-512
- Registered in
- RFC 7518 section 3.5
- Implementation requirement
- Optional
- Key
- RSA key pair, 2048 bits or larger, which leaves ample room for this padding
- Salt length
- 64 bytes, matching the SHA-512 output
- Verified in the decoder
- Yes, in your browser, with a PEM public key.
In detail
A PSS encoded message has to fit inside the modulus with room for the digest, the salt, a mask and a trailer byte. SHA-512 with a 64 byte salt needs a little over 1040 bits of that space, which is comfortable at 2048 bits and impossible at 1024. It is the clearest illustration of why RFC 7518 sets a floor on the key size rather than leaving it to the deployment.
Beyond that, PS512 behaves like the other PSS variants: randomized signatures, a signature the length of the modulus, an ordinary RSA key pair shared with RS512 if you want it. There is no size penalty in the token for the larger hash, and on 64 bit hardware SHA-512 is fast, so the practical cost against PS256 is close to nothing.
It is also the rarest of the six RSA options. Where PS256 has been pulled into the mainstream by financial grade profiles, PS512 turns up mainly in estates that standardized on SHA-512 everywhere. Choosing it means accepting the narrowest implementation support in exchange for headroom nobody currently needs.
The decoder verifies PS512 in your browser with a PEM public key. For an algorithm this uncommon that is often the only quick way to establish that a token is well formed and correctly signed, before spending time on a gateway or client library that may simply not implement it.
Examples
// PS512 encoded message, approximate space needed
// 64 byte digest + 64 byte salt + mask + trailer ~= 1041 bits
RSA 1024 bit key -> cannot encode PS512
RSA 2048 bit key -> fits with room to sparePS256 needs roughly half that, which is why it works on keys that PS512 cannot use at all.
Things that catch people out
- Trying PS512 with a legacy 1024 bit key. The padding does not fit, and the error usually surfaces as an opaque encoding failure at signing time.
- Expecting a longer token than PS256. Signature length follows the key, not the hash.
- Selecting it for a public API. It has the thinnest support of the PSS family, and PS256 or ES256 interoperate far better.
Try it: JWT Decoder
Paste a token to decode the header and payload, read the claims and expiry, and verify the signature in your browser. Nothing is uploaded.
JWT Decoder
LOCAL · Browser-OnlyDecode and inspect JSON Web Tokens without sending them to a server
Related JWT claims and algorithms
All jwt claims and algorithms →PS256: RSASSA-PSS with SHA-256 in a JWT
PS256 signs a JWT using RSA-PSS with SHA-256 and MGF1. How it differs from RS256, why two signatures differ, and verifying with a public key.
PS384: RSASSA-PSS with SHA-384 in a JWT
PS384 signs a JWT using RSA-PSS with SHA-384 and a 48 byte salt. What changes against PS256, and how the decoder verifies one in your browser.
HS512: HMAC with SHA-512 in a JWT
HS512 signs a JWT with a shared secret using HMAC and SHA-512. Secret sizing, the token size cost, and how the decoder verifies one in your browser.
ES256: ECDSA with P-256 and SHA-256 in a JWT
ES256 signs a JWT with ECDSA on curve P-256 using SHA-256. Signature format, why raw R and S beats DER here, and verifying with a public key.
ES384: ECDSA with P-384 and SHA-384 in a JWT
ES384 signs a JWT with ECDSA on curve P-384 using SHA-384. Signature length, where the curve is mandated, and verification in your browser.
ES512: ECDSA with P-521 and SHA-512 in a JWT
ES512 signs a JWT with ECDSA on curve P-521 using SHA-512. Why the curve is 521 bits, what that does to signature length, and how to verify it.
Tools for this
- JWT Decoder Free online JWT decoder - decode and inspect JSON Web Tokens without sending them to a server