The first article in this series about JWT gave an introduction to important certificate file formats while the second article explained JWT in general. This final article in the miniseries includes more information about how signing JWTs works, including code snippets for Java.

The complete source code of this article can be found here.

# Signing JWT in General

A signed JWT consists of a header part, a payload and a signature part at the end, all separated by a period:

(line breaks only for brevity)

So, signing a token means to generate an additional string that gets appended to the unsigned token which consists only of the header and the payload. This additional string is calculated using hashing algorithms and signing algorithms.

# Signing Algorithms and Hashing Algorithms

When signing a JWT, the algorithms to be used have to be specified. Here is an example for creating a signed JWT with the JWT implementation of Auth0:

In this example, the algorithm was specified as “RSA256”. This string actually includes two algorithms, not just one.
It is a combination of a **signature algorithm** and a **hashing algorithm**. A JWT
cannot be signed directly because it is often too long for the signing algorithm. This is solved by not signing the
JWT directly, but sign the hash of the JWT instead. The hash has a fixed, small size and can be used as input for
the signature algorithm. (source)

Often, hashing algorithms of the SHA-family are used.

Examples of signing algorithms are the symmetric HMAC or the asymmetric RSASSA-PKCS1-v1_5.

Here is a table of the supported algorithms of the JWT implementation from Auth0, taken from the official Github repository of Auth0:

JWS | Algorithm | Description |
---|---|---|

HS256 | HMAC256 | HMAC with SHA-256 |

HS384 | HMAC384 | HMAC with SHA-384 |

HS512 | HMAC512 | HMAC with SHA-512 |

RS256 | RSA256 | RSASSA-PKCS1-v1_5 with SHA-256 |

RS384 | RSA384 | RSASSA-PKCS1-v1_5 with SHA-384 |

RS512 | RSA512 | RSASSA-PKCS1-v1_5 with SHA-512 |

ES256 | ECDSA256 | ECDSA with curve P-256 and SHA-256 |

ES256K | ECDSA256 | ECDSA with curve secp256k1 and SHA-256 |

ES384 | ECDSA384 | ECDSA with curve P-384 and SHA-384 |

ES512 | ECDSA512 | ECDSA with curve P-521 and SHA-512 |

The third column describes the combination of signature algorithm and hashing algorithm.

That table elaborates the above Java example: We used a key that was signed with RSASSA-PKCS1-v1_5 with the hash algorithm of SHA-256.

# Sign JWT with symmetric HMAC

The following snippet shows how to sign a JWT with a symmetric HMAC algorithm. To validate the JWT, the receiver has to know the secret which has to be transmitted in a save manner.

# Sign JWT with asymmetric RSA

The RSA algorithm doesn’t need a shared secret between sender and receiver because the receiver can verify the token with the public key of the sender.

# Signing and Encrypting a JWT asymmetrically

Last, here is an example of how to first sign and then encrypt a JWT. As stated above, the complete source code can be found here.

# Further Reading

This here is a great article about which signing algorithm to use.