JWT is a token string which is composed by three parts separated by a dot '.'
character.
Each part is Base64-encoded (not encrypted) so you can get the content of each part by Base64-decoding each part individually. Since Base64-encoded data does not contain the dot '.'
characters this gives the possibility to use it as a separator to join the three parts in any case.
The content of the three sub strings, once the JWT has been split and each individual part Base64-decoded is as follows:
- algorithm used for the signature
- informative content in JSON format
- signature
So in order to retrieve the information brought by the token it is needed to:
- Split the JWT at dot
'.'
characters
- Take the second part and
Base64-decode
it
It has to be considered that the information contained in a JWT is NOT protected by being read, it is protected against modification; so there is nothing wrong in being able to decode and access this information without knowledge of certificates or encryption keys.
The whole process related to the token has three actors:
- the issuer: usually an authentication API
- the bearer: usually the API client application
- the consumer: usually the API which requires it to respond
The third part of the token, the signature, is the element that allows the consumer to be sure the token has not been modified and, for that reason, that the information contained in it can be trusted because had been checked/provided by the issuer.
The bearer is not expected to be able to check the token: it is just expected to receive it from a verification procedure and give it to the API it wants to use. It can eventually access the content, meaning that in the context of the application an access to the token information by the client that received it does not have to constitute a vulnerability. The token has to be delivered to the client (and sent back to the consumer) over a protected channel like SSL / https and this is to protect access to the token by other entities, not by the client which the token is being delivered.
The consumer and issuer are often (but not necessarily) just different API methods of the same application.
The algorithm used for the signature can be a symmetric or asymmetric encryption one.
In the first case the encryption key has to be shared between the issuer and the consumer. Although this may seem a problem it actually is not the case in situations (a quite common case) where the issuer is also the consumer (or at least they are in the same host). In this case the "shared secret" is indeed not shared with anyone.
When the consumer (one or more) needs to be separated by the issuer then an asymmetric encryption can be used so that the issuer keeps the private key and the consumer just have the public key. In this case of course also a symmetric encryption can be adopted but the "shared secret" has to be really shared with the different consumers so evaluations must be done if this can be safely done and maintained.