What are JSON web tokens any why would one want to use them?

26 May 2019 - tsp

JSON web tokens are a standardized form of a token. An access token contains security credentials - for example for an login session or enabling a user to perform a single / multiple actions. It may contain information for the users, the devices or applications identity, the assigned groups or privileges, additional information like the allowed usage and normally should be kept secret like any other identifying information.

There are different token types. Some may only contain an identifier, others may also contain the granted access permissions (but of course not allowing the user to modify them). The first category that’s only containing an identifier and no additional information is called a bearer token. It can be best compared to a password and has to be verified by the targeted service - for example by comparing it against a session ID store or some other shared database. Of course this might be inpracticle due to scaling constraints (distributing millions of new tokens every second to all systems in a connected system of clusters worldwide is simply impossible, building a distributed store may not perform as well as one want’s to) or due to security constraints (it requires a single authority that verifies tokens or requires applications to have access to the token store).

JSON web tokens take another route. They contain identity information and optionally additional constraints (like the issuer, the audience, and expiration and validity time, an unique identifier) and optionally information required for authorization (users groups, resource IDs, embedded additional tokens for backend services, etc.). The service that verifies the tokens can use either a shared known secret - in this case an keyed-hash message authentication code (HMAC) is applied to the JSON data - or verify a signature against a known public key used by the token creating system (RSA signatures using RSASSA-PKCS1-v1_5 with SHA-256 hash or ECDSA using P-256 curve and the same hash algorithm).

Additionally tokens may also be encrypted (for example when they contain information that should not be known to the users).

The approach of using signed tokens has multiple advantages:

Of course using such tokens also has a drawback:

Normally the problem of missing logout functionality is solved by using two different types of tokens. Simple signed and expiring tokens that live only a short time (for example 6 hours) that can be used in a decentralized way and long living tokens that can be used to renew the short lived ones which will trigger a validation against a shared authentication database (i.e. using signed tokens for short lived tokens and bearer tokens as long lived ones).

Of course one has to keep in mind that tokens have to be transmitted on every access in case of a REST system (like HTTP applications) so their size somewhat matters. Also their storage in HTTP context will most likely be a cookie - since the size of a cookie is limited to 4 KByte on most browsers and a maximum of 50 cookies (one could chain multiple ones in many implementations - but there are some out there who limit to 4 KByte anyways) one should limit the size to approximately 4 KByte.

How is a JWT structured

Basically the content of a JWT is just a JSON object containing all claims. An additional header is built (that’s also a JSON structure) that contains algorithm and type information. The Algorithms are typically HS256 (HMAC with SHA256) or RS256 (RSA signatures with SHA-256). In theory the method none would also be specifyable but of course since that would allow modification of the tokens by the user which is just something one doesn’t want to occure (since one wants to trust token content).

The Token itself consists of the base64 encoded header followed by a dot, the base64 encoded payload followed by a dot and the base64 encoded hash or signature.

For example the content

{
   "iss":"Test RSA Issuer 3",
   "iat":1558889251
}

could result in a token like the following (RS512 token using an 4096 bit RSA key) 780 byte token:

eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzUxMiJ9.eyJpc3MiOiJUZXN0IFJTQSBJc3N1ZXIgMyIsImlhdCI6MTU1ODg4OTA5Mn0.bNYUfzyo21dEL6F7t0dkCnjtfNvom5AdsOwUxxNKp9Qb9RqPGpAtfhSFKnDDEc97FxSTzD5uHFF96uHKymtGcj1BGY7GYuVETqNN2TVHYQtgJmAta-34UI90-n_qPLSFEN372vUCtUSj7sNNs-uZdBf5SZN7ACILvuqzzya9D3af4atcKCyxniC7BC3L7s9jhhD55fropKr86KPoouH4rjdAXOgCkLetzQbKWrAoLXlzWLJbEu2NCw5eAuwnBox6gmNahSF6RnVQ57pWC8q3oNj8FjW10TLURqLOJFtH22XdE91UZiaqgnqeDt6mu0gNwbrvqkDfdBrE4Kqprs2LHI80eOiNlAEvWEE_rGj06_yjE_M5-AGv7DqzxLjndnj9DhKkPXCh8v6haVaJ91QLvTwe84eIPPZrw87bVl1mqkU6SnOCWCjE2-9iH7FRQlAqd0OvYbicU3ohHsqPAZK9bx6oI6lDcXAWYBUuGE1iOcSvGpTa1Y45UYB3PT8faBmkwEhpD9XJKkXYVmXaeJABEYb_te31814rLfZ34hUhXM0Obqx-Sq_ZZGNXz74K0NrFcxUUiCCFHCS6vMteLgeCOiIW7iUwq7pc0DGnqe-KnLcX8iA5H3Miak9yd5IsuBuzCyzLoV-jdLcx2aD9w8sDR4T4lB7DZ7M38MWFCZw6mY0

Which claims are standardized

Implementations

There are many implementations out there. One can see an impressive list at jwt.io. I’ve also implemented a subset (only signed, not encrypted tokens) in PHP and Java.

This article is tagged: Internet, Security, Web


Dipl.-Ing. Thomas Spielauer, Wien (webcomplains389t48957@tspi.at)

This webpage is also available via TOR at http://jugujbrirx3irwyx.onion/

Valid HTML 4.01 Strict Powered by FreeBSD IPv6 support