JWTs: Which Signing Algorithm Should I Use? (2024)

JSON Web Tokens (JWTs) can be signed using many different algorithms: RS256, PS512, ES384, HS1; you can see why some developers scratch their heads when asked which one they would like to use.

In my experience, many of the mainstream identity providers have historically only offered RS256 or at least defaulted to it.However, thanks to initiatives such as Open Banking, these identity providers are now expanding their support to cover more signing algorithms, which means you will need to start understanding which ones to use.

I am not a cryptographer, but through my work with OpenID Connect and FIDO2, I have gained a practitioner’s understanding of the various signing algorithms and the cryptography communities’ general feelings towards each one.In this article, I’m going to arm you with some of that knowledge so that you can understand what each “alg” value means and choose the best signing algorithm available to you.

TL;DR: EdDSA > ECDSA or RSASSA-PSS > RSASSA-PKCS1-v1_5 and know what to expect.

Algorithm (alg) Values

Before we look at each family of signature algorithms, let’s first clarify what we mean by “alg” values such as RS256.These are JSON Web Algorithms (JWA), which are part of the JavaScript Object Signing and Encryption (JOSE) family.You’ll see “alg” values in JWT headers, telling you how the JWT was signed, and in JSON Web Keys (JWK), telling you what algorithm a key is used for.

As a general rule of thumb, an “alg” value can be broken down as:

RS

256

signature algorithm

hashing algorithm

  • Signature algorithm family: In this case, RS means RSASSA-PKCS1-v1_5.
  • Hashing algorithm used by the signature algorithm. In this case, 256 means SHA-256.

Most signing algorithms have variants for SHA-256, SHA-384, and SHA-512.In some cases, you can even have something like “RS1”, which uses SHA-1 🤢 and is required for FIDO2 conformance.

These algorithms are typically defined in RFC 7518, but you can find a full list of supported algorithms in the JOSE IANA registry.

Which Hashing Algorithm Should I Use?

SHA-256, SHA-384, and SHA-512 are all variations of the same hashing algorithm family: SHA-2.

As a rule of thumb, the number in an algorithm refers to the size of the hash it will generate.For example, SHA-256 will produce a 256-bit hash, while SHA-512 will produce a 512-bit hash.

The level of security each one gives you is 50% of their output size, so SHA-256 will provide you with 128-bits of security, and SHA-512 will provide you with 256-bits of security.This means that an attacker will have to generate 2^128 hashes before they start finding collisions, thanks to the birthday bound.This is why we use a minimum of 128-bit security.

You’re not going to be needing anything better than SHA-256 any time soon.Just don’t use SHA-1.

Validation: Know your Algorithm

Every application validating JWT signatures should know ahead of time which algorithms to expect and exactly which key to use.You can do this by assigning each public key to an algorithm (e.g. this key is for RS384, this one for ES256).When you have many keys for a single algorithm, you can use the key ID (kid) in a JWT header to understand which one to use.

Basically, you want to make sure the kid and alg values in a JWT match what you expect.If they do not match, then someone is up to no good.

{ "typ": "JWT", "kid": "123", // is this key... "alg": "RS256" // ...allowed to be used for this algorithm?}

Protocols such as OpenID Connect facilitate this using a discovery document and a JSON Web Key Set (JWKS) available on an endpoint protected by TLS.

These days, you should not trust the “alg” value in the JWT header alone, nor should you accept JWTs with an algorithm of “none” or JWTs with a public key embedded in its header.

RSASSA-PKCS1-v1_5 (e.g. RS256)

RS256 = RSASSA-PKCS1-v1_5 using SHA-256

While RSAES-PKCS1-v1_5 is no longer safe for encryption, RSASSA-PKCS1-v1_5 is still suitable for digital signatures.As I mentioned earlier, in my experience, RS256 has historically been the default for most JWT implementations, with many SaaS identity providers only offering this signature algorithm.It’s hard to find a system that can’t support JWTs signed with RS256.

JWTs signed with RSASSA-PKCS1-v1_5 have a deterministic signature, meaning that the same JWT header & payload will always generate the same signature.

RSASSA-PKCS1-v1_5 has been around for a long time, but these days, you should generally prefer RSASSA-PSS (RSA with a probabilistic signature).That’s not to say RSASSA-PKCS1-v1_5 is broken but rather that RSASSA-PSS simply has desirable features that the other does not.In fact, RFC 8017 now considers RSASSA-PSS a requirement when using RSA for signing:

Although no attacks are known against RSASSA-PKCS1-v1_5, in the interest of increased robustness, RSASSA-PSS is REQUIRED in new applications.

That being said, when discussing Bleichenbacher’s attacks against the RSA PKCS#1 encryption and signature standards, David Wong in Real-Word Cryptography shares an interesting statistic:

Unlike the first attack that broke the encryption algorithm completely, the second attack is an implementation attack [against signature validation].This means that if the signature scheme is implemented correctly (according to the specification), the attack does not work.

Yet, it was shown in 2019 that many open source implementations of RSA PKCS#1 v1.5 for signatures actually fell for that trap and mis-implemented the standard, which enabled different variants of Bleichenbacher’s forgery attack to work!

Since the attacks are against signature validation, you will have to be confident that all recipients who validate your JWTs are using a library that is not vulnerable to Bleichenbacher’s attack.That would be difficult if you are dealing with many 3rd parties.

The work around Open Banking, such as OpenID’s Financial-grade API (FAPI), does not allow the use of RSASSA-PKCS1-v1_5.For my regular readers, this was the only algorithm available in IdentityServer up until IdentityServer4 version 3.

Further Reading

  • Learn how to generate RSA keys for JWT signing using OpenSSL

RSASSA-PSS (e.g. PS256)

PS256 = RSASSA-PSS using SHA-256 with MGF1 with SHA-256

RSASSA-PSS is the probabilistic version of RSA, where the same JWT header and payload will generate a different signature each time.Unlike other algorithms, this is probabilistic in a good way; while a random value may be used during signature generation, it is not critical to security.In general, it’s a lot simpler to implement and therefore harder to get wrong.

If you want to use an RSA key, then it’s recommended that you use RSASSA-PSS over RSASSA-PKCS1-v1_5, but luckily an RSA key can be used for either signature scheme.Signature length is also identical between the two.

The UK’s Open Banking initially mandated the use of PS256, but later opened it up to ES256.

Further Reading

  • Learn more about RSASSA-PSS and how to use it in .NET Core
  • Learn how to generate RSA keys for JWT signing using OpenSSL

ECDSA (e.g. ES256)

ES256 = ECDSA using P-256 and SHA-256

In the case of Elliptic Curve Digital Signing Algorithms (ECDSA), the number in ES256 that refers to the hashing algorithm also relates to the curve.ES256 uses P-256 (secp256r1, aka prime256v1), ES384 uses P-384 (secp384r1), and, the odd one out, ES512 uses P-521 (secp521r1).Yes, 521.Yes, even Microsoft has typoed this.

Elliptic Curve Cryptography (ECC) is much harder to crack than RSA (or maybe we are just really good at breaking RSA).As a result, ECDSA can use much shorter keys than RSA along with much shorter signatures.A short Elliptic Curve (EC) key of around 256 bits provides the same security as a 3072 bit RSA key.

You will often see ECDSA listed as faster than its equivalent in RSA, but this is only really true for signature generation; signature validation is still typically faster with RSA.With JWTs, you’re most likely going to be signing once and verifying many times.

JWTs signed with ECDSA have a probabilistic signature, meaning that the same JWT header & payload will always generate a different signature.But unfortunately, ECDSA is probabilistic in a bad way, where random generation is vital to the security of the signature.

ECDSA uses a random nonce (no more than once) that is generated per signature.Failure to only ever use a nonce value once makes the private key easily recoverable, and this has been seen in the wild with both Sony’s Playstation 3 and Bitcoin.With the Playstation 3, the private key was recovered due to a static nonce, and with Bitcoin, Android users were affected due to a bug in Java’s SecureRandom class on Android.If random values are required for the security of a probabilistic signature, then you should prefer a deterministic signature that does not.

Whereas RSASSA-PKCS1-v1_5 has issues with signature validation, ECDSA has issues with signature generation, which is much easier to deal with when you are the token issuer.

ECDSA is gaining popularity but seems to generally be frowned upon by cryptographers due to how elliptic curve cryptography was implemented, with concerns around implementation difficulty due to the use of random values.It has a better reputation than RSA, but cryptographers are still advocating the migration to EdDSA.

The curves JOSE initially used where defined by NIST.If you are concerned about using curves defined by NIST but want to use ECDSA, a popular alternative is to use a Koblitz curve, such as secp256k1 (as opposed to secp256r1).Kobiltz curves are a few bits weaker, but if you have concerns that the unexplained random numbers used in the NIST curves indicate another NSA backdoor, then Kobiltz curves offer an increasingly popular alternative.You can find usages on these curves in Bitcoin, Ethereum, and FIDO2.However, you should be using EdDSA if you want to use a non-NIST curve.In JOSE, algorithms using Kobiltz end with a K, e.g. ES256K.

Further Reading

  • Learn how to use ECDSA in .NET Core and how to sign tokens with ECDSA in IdentityServer4
  • Learn how to generate EC keys for JWT signing using OpenSSL
  • Use custom JWT signing algorithms in .NET Core, with examples using Kobiltz curves

EdDSA

EdDSA = an EdDSA signature algorithm was used 🤷‍♂️

EdDSA bucks the trend of the previous algorithms and uses a single alg value.Instead, it relies upon the curve (crv) defined in a pre-agreed key.

For example, a JWK containing an EdDSA public key would look like the following:

{ "kty": "OKP", "alg": "EdDSA", "crv": "Ed25519", "x": "60mR98SQlHUSeLeIu7TeJBTLRG10qlcDLU4AJjQdqMQ"}

This forces the modern behavior of using the curve assigned to the key,as opposed to from the JWT, and eliminates various alg related attacks.

EdDSA is a form of elliptic curve cryptography that takes advantage of twisted Edwards curves.It is a variant of Schnorr’s signature system (rather than DSA).EdDSA is fast at both signing and validation, has a short signature, and side-steps whole classes of security vulnerabilities.

RFC 8037 defines JOSE support for the following EdDSA variants:

  • Ed25519: a 255-bit curve Curve25519 (32-byte private key, 32-byte public key, 64-byte signature). Signing uses SHA-512. Provides 128-bit security
  • Ed448: a 448-bit curve Curve448-Goldilocks (57-byte private key, 57-byte public key, 114-byte signature). Signing uses SHAKE256. Provides 224-bit security

JWTs signed with EdDSA have a deterministic signature, meaning that the same JWT header & payload will always generate the same signature.This is deterministic in a good way, addressing the concern of relying on random nonce values to protect the private key.EdDSA only uses random values during private key creation.This is the algorithm that .

Support for EdDSA in JWT libraries is a little patchy, but expect to see more of EdDSA soon.

Further Reading

HMAC (e.g. HS256)

HS256 = HMAC using SHA-256

Up until now, we’ve been talking about asymmetric cryptography, where only the token issuer has the private key to create the signature, and everyone else has the corresponding public key that can be used to validate the signature.For example, the identity provider has the private key and relying parties use a public key.

In the rare event that you will be the only person who issues and validates tokens, then you could consider using symmetric cryptography with something like HS256.This uses the same key to both create and validate a signature.

In my opinion, if you find yourself in this position, then I don’t think JWTs are the right solution for you.If the same entity is both reading and writing, then what is the requirement for round-tripping structured, plaintext data in a JWT?I would recommend storing the data in a database and passing around a reference or to use something like a Branca token or JSON Web Encryption (JWE) to ensure only you can read the data.

Generally, using HMAC for JWT signing is seen as something of an anti-pattern.

Further Reading

  • Learn more about JSON Web Encryption (JWE) and how to use JWE in .NET
  • Learn how to use Branca tokens with ScottBrady.IdentityModel

None

none = base64 encrypted

Sorry, I couldn't resist.Please don’t use this.

Recommendations

Use EdDSA where possible and use ECDSA when it is not.If you are forced to use RSA, prefer RSASSA-PSS over RSASSA-PKCS1-v1_5.

I don’t think it’s a controversial statement to say that RSA is slowly on its way out.At the moment, offering ECDSA is a good alternative, but ideally, you’ll be wanting to move to EdDSA where possible.

But, no matter which algorithm you use, make sure you know ahead of time which algorithm to expect and which key to use for validation.

A huge thank you to Neil Madden for the technical review of this blog post.

JWTs: Which Signing Algorithm Should I Use? (2024)

FAQs

What is the best algorithm for JWT signing? ›

All a signature does is ensure that the message is authentic, which it achieves by allowing the recipient to compare the data they've received with a trusted claim included in the data (the signature). JWTs are most commonly signed using one of two algorithms: HS256 (HMAC using SHA256), and RS256 (RSA using SHA256).

What is the signing key algorithm for JWT? ›

JWT signing algorithms can be classified into two categories: symmetric and asymmetric. Symmetric algorithms use the same secret key to sign and verify the tokens, while asymmetric algorithms use a pair of public and private keys.

Which is better, HS256 or RS256? ›

Which Should You Use? While both HS256 and RS256 can be used to verify the integrity of JWTs, the recommended algorithm at this time is RS256. A signature must ensure authenticity, which means that the JWT content is the same as that generated by the sender. Both HS256 and RS256 algorithms ensure JWT authenticity.

Which signature algorithm to use? ›

The most secure practice, and our recommendation, is to use RS256 because: With RS256, you are sure that only the holder of the private key (Auth0) can sign tokens, while anyone can check if the token is valid using the public key.

Which algorithm is best for authentication? ›

In summary, RSA, DSA, ECDSA, HMAC, and Bcrypt are some of the cryptographic algorithms that are best suited for providing digital authentication services such as message signatures or identification credentials.

Which digital signature algorithm is most secure? ›

DSA is a faster algorithm and is simpler to implement than RSA. DSA is more secure than RSA as it provides message integrity and non-repudiation.

How long should a JWT signing key be? ›

A key of size 2048 bits or larger MUST be used with these algorithms. The minimum key length for ECC is not specified in the RFC. Please consult the RFC for more specifics about other algorithms. You should rotate your token signing keys regularly.

What is the secret signing key of JWT? ›

The signing key is a JSON web key (JWK) that contains a well-known public key used to validate the signature of a signed JSON web token (JWT). A JSON web key set (JWKS) is a set of keys containing the public keys used to verify any JWT issued by the authorization server and signed using the RS256 signing algorithm.

Are OAuth and JWT the same? ›

Here are some differences between OAuth and JWT: Main function: OAuth is used for authorization, while JWT is used for authentication and exchanging information. Security: OAuth is a secure way to manage authorization flows, while JWT is a lightweight and self-contained token.

Which is not secure enough for the HS256 algorithm? ›

WeakKeyException: The verification key's size is 64 bits which is not secure enough for the HS256 algorithm. The JWT JWA Specification (RFC \7518, Section 3.2) states that keys used with HS256 MUST have a size >= 256 bits (the key size must be greater than or equal to the hash output size).

What is the fastest signature algorithm? ›

ECDSA (P256) and EdDSA (Ed25519) are generally the fastest for signing, but RSA is the fastest for verification. SM2 is generally slower that the equivalent ECDSA, EdDSA and RSA methods for verification.

Which JWT algorithm is best? ›

When signing is considered, elliptic curve-based algorithms are considered more secure. The option with the best security and performance is EdDSA, though ES256 (The Elliptic Curve Digital Signature Algorithm (ECDSA) using P-256 and SHA-256) is also a good choice.

How are JWTs signed? ›

JWTs can be signed using a secret (with the HMAC algorithm) or a public/private key pair using RSA or ECDSA. Although JWTs can be encrypted to also provide secrecy between parties, we will focus on signed tokens.

How do you find the signature algorithm? ›

The Signature Algorithm can be checked in the General Information menu: Also, you can scroll the page down and view the certificate information indicates the Signature Algorithm of the certificate along with other information in the Raw OpenSSL Data window. There is a convenient decision for OpenSSL users as well.

What is the RS256 algorithm for JWT? ›

RS256 → In RS256 Algorithm a pair of public-private keys are used to encrypt and decrypt the data. The JWT header and payload are hashed by the issuer using SHA256, and they are then encrypted with their private key and the RSA encryption technique.

Is the HS512 algorithm secure? ›

HS512 is generally considered more secure due to its longer signature, but HS256 provides a slightly better performance.

What is the recommended algorithm for Jwe? ›

Working with Different JWE Algorithms

The most commonly recommended option for asymmetric key encryption is ECDH-ES, while AES-GCM (with key wrapping) is the recommended alternative for symmetric encryption setups.

What is the difference between ECDSA and RSA? ›

Key size. The RSA algorithm uses significantly larger cryptographic keys than ECDSA. To reach 128-bit security, RSA needs to use keys that are at least 3072 bits in length. Meanwhile, it's sufficient for ECDSA to generate public keys twice the size of the desired 128-bit security to reach this standard.

Top Articles
Latest Posts
Article information

Author: Margart Wisoky

Last Updated:

Views: 6501

Rating: 4.8 / 5 (58 voted)

Reviews: 81% of readers found this page helpful

Author information

Name: Margart Wisoky

Birthday: 1993-05-13

Address: 2113 Abernathy Knoll, New Tamerafurt, CT 66893-2169

Phone: +25815234346805

Job: Central Developer

Hobby: Machining, Pottery, Rafting, Cosplaying, Jogging, Taekwondo, Scouting

Introduction: My name is Margart Wisoky, I am a gorgeous, shiny, successful, beautiful, adventurous, excited, pleasant person who loves writing and wants to share my knowledge and understanding with you.