How to generate the signed and encrypted JWT access token in FusionAuth - jwt

I am using FusionAuth. We have created one application in it. It is an OAuth application.
It generates the JWT access token. I copy the access token and past it in the https://jwt.io/ debugger and see that, it is able to decode the JWT token and I am able to see the payload of the JWT. As this JWT is only signed and not encrypted.
Here, I want to generate the JWT as encrypted, So how I can generate JWT access token as encrypted, So basically I want a Signed and encrypted JWT and how fusion will validate it if we find a way to generate the JWT in an encrypted way?
Thank you.

FusionAuth does not currently support JWT encryption, we only support signing using HMAC, RSA or EC algorithms.
You could sign and encrypt a JWT outside of FusionAuth but FusionAuth will not be able to validate the signature.
If this is something you'd like to see in FusionAuth please open a feature request on our GitHub issues repository.
Thanks!

You have to add some secret string (salt) in second parameter just like this :
var token = jwt.sign({ foo: 'bar' }, 'I'm-secret-Salt ')

Related

JWT - asymmetric encryption

I have three servers:
- authorization server
- api server
- frontend server
Authorization server returns JWT self-contained access token (+refresh token). JWTs aren't stored anywhere in Authorization Server.
I want to secure JWT with asymmetric encryption and i am not sure if i my idea is correct.
Let me describe flow:
After login from Fronted Server, Authorization server gets user credentials, then generates JWT token and encode it with public key.
Fronted Server receives encrypted JWT token and client (web browser) saves it as HTTP-Only cookie.
Client sends request to secured resource, so FrontEnd based on obtained encoded JWT token, requests for secured data API Server.
API Server based on secured JWT and private key decrypt value and checks if user has enough access to perform operation.
If JWT token expires, front end sends request to Authorization Server with refresh token to get new JWT token.
In this case Authorization Server and API Server would need to store private key for decryption.
Is this solution secure enough? Is it OK to store the same private key in two servers?
Do you know if flow is correct? Or maybe data flow should be different?
I want to secure JWT with asymmetric encryption and i am not sure if i my idea is correct.
In general, data encryption is a good idea. Especially if you transport sensitive data.
Let me describe flow
[…]
In this case Authorization Server and API Server would need to store private key for decryption. Is this solution secure enough? Is it OK to store the same private key in two servers? Do you know if flow is correct? Or maybe data flow should be different?
If I understand correctly your flow, the token is encrypted on AS (Authorization Server) side and decrypted on API server side. Therefore you want to prevent the client from reading its content.
This flow is absolutely fine. Both the AS and the API server will have the shared secret so that they will be able to encrypt or decrypt the token.
I suggest you to read more about JWE (encrypted JWT) and the associated RFC7516. This specification describes a standard way to encrypt tokens.
Depending on the programming language you use, you may found libraries that support JWE. https://jwt.io/ lists lot of libraries and some of these support more than signed tokens (JWS). For example com.nimbusds/nimbus-jose-jwt (Java) or web-token/jwt-framework (PHP).
A possible flow could be as follow. Please not that it will undoubtedly create complexity in your AS and API server code. So before you implement it, you should make sure it is necessary to encrypt your tokens! (e.g. you transport sensitive data)
The AS sign the token with its private key (e.g. algorithm RSxxx, PSxxx or ESxxx) => JWS
The JWS is encrypted as per the RFC7516 with an asymmetric encryption algorithm (e.g. AxxxKW or AxxxGCMKW) and the shared key => Nested token (a JWS in a JWE)
The Nested token is sent to the client
The client cannot read the content, but the token can be sent to the API server as usual
The API server decrypts the JWE with the shared key to get the JWS
The API server verifies the JWS with the AS public key

What is a secret key in JWT

I am unable to clearly grasp how JWT works, esp. the signature part.
Once a client submits correct username and password, the authentication server creates a JWT token consisting of header, payload/claims and signature.
Question 1 - Is signature some secret key (not the user's password) which only the authentication server knows (sort of a private key of the server)?
Question 2 - Say I am using a separate application server and authentication server, on receiving JWT from client, would the application server send the JWT to authentication server to get it validated? I suppose the application server cannot validate a JWT token as it doesn't know the secret key used to sign the header and payload.
Question 3 - I took the following JWT and pasted it on jwt.io. I see the message Signature Verified. How does jwt.io know that the signature is correct as it doesn't know the secret key.
eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOiIxLS9tSjVsVTNYc09QWCt2VitpaGZRMWlCUDVjUTROQm1hNDluOE9rS1FFSnEzTDFNOTl2VW9iQ1ZLUHVYMmdlWWhYaHJQM0t3bHY4SE1RaHNGdnFjbllIeGxGSHM9IiwiaXNzIjoicGxheS1zaWxob3VldHRlIiwiZXhwIjoxNTI2MjgxMDU1LCJpYXQiOjE1MjYyMzc4NTUsImp0aSI6IjhmOGM3YTVmYWRkNTE5MjUxNzQ5NGE4N2Q1ODcxZjJjZGUxZDkzMDdkOTY1MThjNjg2NzExOTc1YjU3M2I5NDBlZWU2NGY0NDUwYzcxODI3NGZmNzU1MmE2Y2JlNTVmZmZhMWI1ZjA3ZWZlOWVkNTE0Y2Y4YTViOTZlM2ExYjI0ODRmYTI5NjZiYjA0ODlmODIwZjMyMzM5YWVhNjM3NWRkZmU4ZDE4N2E2NzBjMzg0ODgwZGIyMzQ1ZTFkMzRkYWNjZmY2MTdkMDY1NzU3YmEwZTQzNDg4YWFhZmZmNDNjYWZlZGY0OTFlODU1YTA0NWM0NmJjNDY4NGYzODlmY2YifQ.GwN6TSNd426xpc3Y02eRXHbrmSr_61MMBqrmx66Ofqs
Question 1 - Is signature some secret key (not the user's password) which only the authentication server knows (sort of a private key of the server)?
No, the electronic signature is a mathematical computation applied to the payload of the JWT using a secret key. The purpose is to ensure that the message has not been altered and to recognize the signer to validate the JWT
Question 2 - Say I am using a separate application server and authentication server, on receiving JWT from client, would the application server send the JWT to authentication server to get it validated? I suppose the application server cannot validate a JWT token as it doesn't know the secret key used to sign the header and payload.
Not necessarily. If a symmetric key (HMAC) is used, the signature and verification key is the same. In that case the Authorization server must know the secret key or send the token to verify. However, if an asymmetric key (RSA, ECDSA) is used, the signature key is different from the verification key. The authorization server can have a copy of the public key safely
Question 3 - I took the following JWT and pasted it on jwt.io. I see the message Signature Verified. How does jwt.io know that the signature is correct as it doesn't know the secret key.
jwt.io or anyone who wants to verify the token needs the secret key. Note that if you copy-and-paste the token in jwt.io, the signature is not verified, but if you change the secret key, the editor changes automatically the signature creating a new token at the time
Signature is just hashing using secret key generated by authentication server, using algorithm specified in header, a combination of your header, payload, and secret
Only the authentication and/or application server knows that secret. JWT is encoded and signed, but not encrypted. to understand difference between Sign/Hash and Encryption, check this
HMACSHA256(
base64UrlEncode(header) + "." +
base64UrlEncode(payload),
secret)
Signature just verifies or validates whether the message was already hashed before using the same kind of algorithm specified in the header with the secret that is known only by server.
To understand how it works in authenitcation, here is a flow:
User sign in, you send user/pass to server in an encrypted way over https
Server validates username/pass from your db
Server generates a JWT and send it back to you, The signature is used here to verify the message wasn't changed along the way.
Server saves the JWT somewhere in a session store.
Later, user requests a server (send JWT everytime it needs something from the server)
Server validates it using same type of hash algorithm that is in the header and secret stored in there.
Server checks whether it is already there in session store.
Servers authorizes and grants you for the request.
I would recommend you read this article that is more descriptive to better understand how it works.

JWT. Why is it better than oAuth and what's the signature?

I'm reading about JWT and I'm confused about why there's a signature:
JWT site
What is the purpose of the signature if it's just a hashed version of the header and payload?
Also, why not just use oAuth? Or whatever 2 factor auth uses?
The purpose of Oauth2 and JWT is different, so it is not possible to compare them directly
JWT is a compact way of representing claims to be transferred between two parties (JSON with digital signature).
OAuth2 is an authorization framework used by third party applications (websites, mobile apps) to access on resources on a resource server, without exposing user password. OAuth2 can use JWT as the exchanged token
JWT is self contained and does not need server sessions . The digital signature is performed with server private key and protects the content. Any alteration of the header, the payload or the signature will be detected by the server and reject the token.

Why can i easily decode auth0 id_token on jwt.io?

Okay, i'm developing an Angular 2 app. I've added auth0 authentication, but to me it handles sessions very insecurely. The jwt token is not encrypted and saved inside localStorage. The claims are visible for anyone, they can easily be decoded and revealed. Not to mention, Web Storage itself isn't a secure place.
I'm opting for JWTs because later i want to transform this web app to desktop app with electron and so i cannot use cookie-sessions. My users will have additional information such as roles, which i don't want to look up in db on every request, that's why i would like to store them in jwt. It makes sense to encrypt the data, but auth0 doesn't seem to provide that function.
If claims like roles are stored in localStorage unprotected, what's stopping me to go to firefox console and change the token, e.g. make myself an admin?
If claims like roles are stored in localStorage unprotected, what's stopping me to go to firefox console and change the token, e.g. make myself an admin?
Because JWT is signed, so any alteration to the content or the signature will be detected during validation
The digital signature, the third part of a JWT token like this hhhhhh.ppppppp.ssssss is created using server private key, and is the way you can verify the identity of the issuer of the token and also that it has not been altered
If you want to hide the payload, the JWT specification allows use encryption (see Json Web Encryption-JWE at RFC). If auth0 does not support it, you have a lot of libraries listed in jwt.io
JWT token has two parts: explicit (codet by base64 algorithm) - with payload data like for example exp time or user Id and role etc. and implicit - hash key which guarantee with extremely high probability that any part of explicit data was not change after token was created (by server using it's private key). So in Local/Session storage you can store this explicit part. The full token should be store in httpOnly cookies - then you will be protected against XSS attack (where hacker want to stole you token).
So you can read and change jwt token payload from firefox, but you will be unable to generate implicit hash - and server will reject your token.
So the answer to title question is: because Auth0 id_token is JWT token :)

Do we need to validate JSON Web Token at client/consumer?

I am studying a bit about JSON Web Token. I understood that header+claims get signed by a secret key and the encoded result gets concatenated to "header.claims.signature" and finally sent back to client.
I have some basic doubts:
Do we need to validate the token at client/consumer (once it receives from server, for sake of authenticity)? Is it a standard at all or not necessary? Any example for reference on this?
If the client needs to validate the token, I guess it has to know the secret key to decrypt/decode. Is there any other way to ask client validate on its own without sharing server's secret key?
If client knows the secret key, I guess it can create its own token too. If such is the case, do the server need to accept such tokens (or is application/business dependent?)
Do we need to validate the token at client/consumer
On client side you usually don't validate the token. Treat it just as an opaque token. Keep it safe and use it when making requests to the server.
If the client needs to validate the token, I guess it has to know the secret key to decrypt/decode.
As mentioned above, the client doesn't need to validate the token.
In any cases in which the authentication server (the instance that authenticates the user and issues the token) and the resource server (the instance that owns a proteceted resource and requires a token for authorization) are not the same, signing and validation of the token is usually done with asymmetric algorithms like RS256 in which the private key is used to sign the token and only known by the authentication server, and the public key is used to verify the signature.
If client knows the secret key, I guess it can create its own token too. If such is the case, do the server need to accept such tokens (or is application/business dependent?)
That's why a client should not know the secret key.
When symmetric key algorithms (e.g. HS256), in which the same key is used to sign and verify a signature are used, you can't allow the client to know the key, as it could be abused to create a fake token. Then JWT would be pointless. For asymmetric keys, there's no risk if the client knows the public key.