Signing JSON Web Tokens: Algorithm Tradeoffs, Performance, and Security
CIAM Weekly
SubscribeSign in
Signing JSON Web Tokens: Algorithm Tradeoffs, Performance, and Security
Dan Moore<br>Feb 09, 2026<br>∙ Paid
Share
Heya,<br>You’ve probably seen RS256, ES256, and EdDSA in your JWT signing libraries. But what do those acronyms actually mean for your application’s security and performance?<br>I’ve spent way too much time reading specs and RFCs so you don’t have to.<br>Let’s break down the tradeoffs in plain English. Algorithm choice isn’t academic. It determines how your signatures survive security audits, whether your keys can be recovered from a nonce reuse, and how much bandwidth you burn on every signed token.<br>Aside: this is not a post about encrypted JWTs, which are also a thing. I’ve only seen one in the wild and am not competent to speak on that kind of JWT.<br>Algorithm Names
These algorithm names look like cryptographic alphabet soup, but they follow a pattern.<br>The JOSE (JavaScript Object Signing and Encryption) family defines these algorithms across these RFCs:<br>RFC 7515 - JSON Web Signature (JWS)
RFC 7516 - JSON Web Encryption (JWE)
RFC 7518 - JSON Web Algorithms (JWA)
RFC 8037 - CFRG Elliptic Curve Diffie-Hellman (ECDH) and Signatures in JSON Object Signing and Encryption (JOSE)
RFC 7519 defines JSON Web Tokens but no algorithms. There’s also an authoritative list of algorithms used to sign and encrypt JWTs at the IANA.<br>As I mentioned above, I’m not going to talk about JWE or encryption below. The JWA RFC defines most of the algorithms while JWS and JWE discuss how to apply them to signing and encrypting.<br>Most JWS algorithm names follow a two-part pattern: [Signature Algorithm Family][Hash Function].<br>Let’s break down RS256 as an example:<br>RS: RSASSA-PKCS1-v1_5 (the signature algorithm family)
256: SHA-256 (the hash function’s output size in bits)
So RS256 means: “Use RSASSA-PKCS1-v1_5 signatures with SHA-256 as the hash function.”<br>Similarly:<br>ES384 = ECDSA with P-384 curve using SHA-384
PS512 = RSASSA-PSS using SHA-512
HS256 = HMAC using SHA-256
The letter prefix tells you which signature scheme is being used. The number suffix almost always refers to the SHA-2 hash variant.<br>The Major Algorithm Family Prefixes
Here are the prefixes you might expect to see<br>HS - HMAC with SHA-2 (Symmetric): HS256, HS384, HS512
RS - RSASSA-PKCS1-v1_5 (Asymmetric): RS256, RS384, RS512
PS - RSASSA-PSS (Asymmetric): PS256, PS384, PS512
ES - ECDSA (Asymmetric): ES256, ES384, ES512
EdDSA - EdDSA (Asymmetric)
Notice that EdDSA breaks the pattern and doesn’t have a number suffix. You’ll see why shortly.<br>I also explicitly am omitting the none algorithm. If you aren’t going to sign your JWT, why are you using a JWT at all? Avoid this algorithm which offers a false sense of security.<br>The Hash Function Number
The number refers to the output size in bits of the SHA-2 hash function:<br>SHA-256: Produces a 256-bit (32-byte) hash
SHA-384: Produces a 384-bit (48-byte) hash
SHA-512: Produces a 512-bit (64-byte) hash
SHA-256 is excellent for nearly everything. The main reason to use SHA-512 today is performance on 64-bit systems (it can actually be faster) or when you need longer output for specific protocols. The exception: some compliance frameworks require specific hash sizes (FIPS 140-2 at higher security levels may require SHA-384 or SHA-512).<br>Cryptographic agility (which is the ability to swap algorithms) is generally better than just picking a bigger hash, though.<br>Never use SHA-1. It’s cryptographically broken. Don’t use it.<br>Algorithm Families: What Those Letters Mean
Now let’s dive into what each prefix actually signifies and why you might choose one over another.<br>Hash-based Message Authentication Code
Hash-based Message Authentication Code (HMAC) HMAC is a symmetric message authentication code. The same secret key is used for both signing and verification.<br>HMAC has the following strengths:<br>provably secure since HMAC has a formal security proof
extremely fast, with 5-10 microseconds required per signature, though the exact duration depends on message size and hardware
a simple implementation, which is harder to get wrong than asymmetric schemes
no random numbers needed: completely deterministic
Nothing is perfect, and the HMAC algorithm has weaknesses too. Key distribution is an issue; both parties need the same secret. Any system component which can verify can also sign so you don’t know which system created a signed JWT. Additionally, key compromise results in total failure; if the key leaks, key holders can forge indefinitely.<br>These weaknesses are because it is a symmetric signing algorithm.<br>Known attacks on this algorithm include timing attacks, because naive verification using string comparison can leak information. Always use constant-time comparison (modern libraries do this). Short key attacks, though an implementation detail, affect this algorithm. Using keys shorter than the hash output weakens security and...