JWT ECDSA signing in JavaScript

Hi, my name is Tina! I am a Full Stack Software Developer and Tech Lead from Canada. 🙋🏻♀️
Search for a command to run...

Hi, my name is Tina! I am a Full Stack Software Developer and Tech Lead from Canada. 🙋🏻♀️
No comments yet. Be the first to comment.
Have you ever installed a package by using go install <some-package> and wondered how to uninstall it? Go is really great in that respect. Go packages are a single binary and they’re installed based on how your Go tooling is set up. Provided we have ...

Overview This is the 3rd article in a series of posts about working with Open API to create generated API clients and documentation websites. In the 1st post we went over what we can do with Open API spec files, e.g. generate API clients and documen...

Overview This article is the 2nd in a series of blog posts that discuss using Open API to help with API documentation and API client code generation. In the previous article, we went over how we can generate documentation and API clients using existi...

Overview This article starts a series of Open API-related blog posts. OpenAPI, previously known as Swagger (a name still in use today for many of its tools), is a suite of tools that generate documentation and networking clients for various programmi...

You've probably already seen the scary alert (that's possibly why you're here), but in case you haven't, it looks something like this: NewAppIJustDownloaded pasted from your clipboard Sometimes it h

This article will go through how to implement JWT ECDSA signing to provide trusted, read-only tokens to a front-end app. This example is in JavaScript (Node.js on the back-end), but these concepts can be easily translated to other languages.
The jwt.io website says it best:
JSON Web Tokens are an open, industry standard RFC 7519 method for representing claims securely between two parties. JWT.IO allows you to decode, verify and generate JWT.
It's essentially a way of packaging data up and sharing it so that it can be trusted. Here is an example of what a JWT looks like:
eyJhbGciOiJFUzI1NiIsInR5cCI6IkpXVCJ9.eyJuYW1lIjoiVGluYSIsImVtYWlsIjoiaW5mb0B0aW5hY2lvdXNkZXNpZ24uY29tIiwiaWF0IjoxNTcyMDU4NDc3fQ.UnoPrB9tqBwAJPM8v_5xihFaMdfK0fQdeJFmhhvEpv9Im79eGvuY5HJ2USrc6caBqae4sTBY59nCfjnmg2Hzyw
There are 3 parts to the JWT token, and they are separated by a period:
If you go to the jwt.io website, you will see the following output:

Here is the contents of that token:
{
"name": "Tina",
"email": "info@tinaciousdesign.com",
"iat": 1572058477
}
JWTs are a useful way to share data so it can be trusted. The format is JSON which makes it nice to work with, especially in JavaScript. One of the benefits of using JWT to share data over the wire is that you do not need to verify or validate anything contained in the JWT with a third-party—you can save on the extra network requests to your database and trust the contents of it to be true. One of the drawbacks with using JWTs is, even though they can expire, they cannot be revoked—you should be able to trust the data contained within the token, but whether that data is still relevant is uncertain.
The default implementation of JWT encoding and decoding uses a single private key for both reading and writing. This is fine if you are only reading it on the back-end, where your private key is safe. If you are trying to read a JWT token on the front-end, you do not want to expose the private key. The reason for this is because the private key can be used to both read and write JWT tokens. If you've exposed your private key on the front-end, then you can no longer trust it as anyone could've seen it and could use it to encode data. Exposing your private key is about as good as not even implementing JWT encoding and decoding protections.
ECDSA stands for Elliptic Curve Digital Signature Algorithm. It's essentially a cryptographic strategy for creating private and public key pairs. ECDSA is very similar to how SSH keys work (which use RSA), except it uses a different algorithm. Though not as popular as RSA, it's a safer option with less foot guns. Modern browsers implement ECDSA as a crypto strategy for reading SSL certificates. ECDSA differs from other JWT signing approaches that are symmetrical:
Essentially, to implement JWT with ECDSA, you would follow a series of steps:
First, you'll need to generate a private-public key pair, similar to how SSH keys work. I used OpenSSL to generate my keys. You should keep the private key private, but it's fine if the public key is out there as JWT tokens cannot be authored with this key.
Now that you have your keys, it's time to start making some data. You can encode any JavaScript object. Please note that this data is not private as any JWT token can be decoded on jwt.io whether there's a key or not, so if you are trying to conceal sensitive data, this is not the way to do it. For example, never store passwords or sensitive data with JWT.
Using the public key, use the JWT.verify method to verify the validity of the signature and view the contents of the data. If the signature does not pass, you should obviously not trust it. There is a method available in the referenced library to decode JWT tokens without verifying the signature. You want to make sure you use verify so that you verify the signature.
JWT.verifyThis JWT ECDSA implementation will have all the code examples you need.
Asymmetrical signing with private-public key pairs is useful if you ever need read-only access to data on the front-end. As specified above, if you plan on reading JWT tokens on the front-end, you definitely want to use an implementation that leverages private and public key pairs. This is because if you expose your private key to the front-end, there's actually no point to even using JWT tokens as this data can now be forged and is no longer trustable. Implementing JWT ECDSA signing is a full stack effort where the back-end does most of the heavy lifting, and the front-end reads it.