1
votes

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:

  1. After login from Fronted Server, Authorization server gets user credentials, then generates JWT token and encode it with public key.
  2. Fronted Server receives encrypted JWT token and client (web browser) saves it as HTTP-Only cookie.
  3. Client sends request to secured resource, so FrontEnd based on obtained encoded JWT token, requests for secured data API Server.
  4. API Server based on secured JWT and private key decrypt value and checks if user has enough access to perform operation.
  5. 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?

1
Usually the content of the token isn't a secret, but you want to guarantee that it was produced by the authorization server. That would point to signing rather than encryption, and only the authorization server should have the signing key.Damien_The_Unbeliever
I'd strongly recommend using existing components rather than trying to roll something yourself here. E.g. if you are in a .NET-based stack, Identity Server might be an option.Damien_The_Unbeliever
Unfortunatelly i cannot proceed with standard approach. Anyway if your auth server signs token, then how possibile backend would verify signature?bontade
When you use an asymmetric algorithm for signing, the private key is used for signing and the public key for verification. There's no need to share the private key, only the auth server knows the private key.jps
Then how backend server will know what are user permissions without decrypting whole token?bontade

1 Answers

2
votes

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