DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Please enter at least three characters to search
Refcards Trend Reports
Events Video Library
Refcards
Trend Reports

Events

View Events Video Library

Zones

Culture and Methodologies Agile Career Development Methodologies Team Management
Data Engineering AI/ML Big Data Data Databases IoT
Software Design and Architecture Cloud Architecture Containers Integration Microservices Performance Security
Coding Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Culture and Methodologies
Agile Career Development Methodologies Team Management
Data Engineering
AI/ML Big Data Data Databases IoT
Software Design and Architecture
Cloud Architecture Containers Integration Microservices Performance Security
Coding
Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance
Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks

Modernize your data layer. Learn how to design cloud-native database architectures to meet the evolving demands of AI and GenAI workkloads.

Secure your stack and shape the future! Help dev teams across the globe navigate their software supply chain security challenges.

Releasing software shouldn't be stressful or risky. Learn how to leverage progressive delivery techniques to ensure safer deployments.

Avoid machine learning mistakes and boost model performance! Discover key ML patterns, anti-patterns, data strategies, and more.

Related

  • Floyd's Cycle Algorithm for Fraud Detection in Java Systems
  • Introduction to Polymorphism With Database Engines in NoSQL Using Jakarta NoSQL
  • JSON Handling With GSON in Java With OOP Essence
  • Proper Java Exception Handling

Trending

  • The Role of Functional Programming in Modern Software Development
  • Testing SingleStore's MCP Server
  • It’s Not About Control — It’s About Collaboration Between Architecture and Security
  • Debugging Core Dump Files on Linux - A Detailed Guide
  1. DZone
  2. Coding
  3. Languages
  4. Using JSON Web Encryption (JWE)

Using JSON Web Encryption (JWE)

JSON Web Encryption (JWE) could be used when one needs to add sensitive information to a token that one would not want to share with other systems.

By 
Viacheslav Shago user avatar
Viacheslav Shago
·
Jan. 03, 23 · Tutorial
Likes (9)
Comment
Save
Tweet
Share
40.2K Views

Join the DZone community and get the full member experience.

Join For Free

In the previous article, we looked at signed JSON Web Tokens and how to use them for cross-service authorization. But sometimes, there are situations when you need to add sensitive information to a token that you would not want to share with other systems. Or such a token can be given to the user's device (browser, phone). In this case, the user can decode the token and get all the information from the payload.

One solution to such a problem could be the use of JSON Web Encryption (JWE), the full specification of which can be found in RFC7516.

JSON Web Encryption (JWE)

JWE is an encrypted version of JWT and looks like this:

JSON Web Encryption

It consists of the following parts separated by a dot:

 
BASE64URL(UTF8(JWE Protected Header)) || '.' ||
BASE64URL(JWE Encrypted Key) || '.' ||
BASE64URL(JWE Initialization Vector) || '.' ||
BASE64URL(JWE Ciphertext) || '.' ||
BASE64URL(JWE Authentication Tag)


JWE Protected Header

For example:

 
{
  "enc": "A256GCM",
  "alg": "RSA-OAEP-256"
}


where

  • alg – The Content Encryption Key is encrypted to the recipient using the RSAES-OAEP algorithm to produce the JWE Encrypted Key.
  • enc – Authenticated encryption is performed on the plaintext using the AES GCM algorithm with a 256-bit key to produce the ciphertext and the Authentication Tag.

JWE Encrypted Key

Encrypted Content Encryption Key value.

JWE Initialization Vector

Randomly generated value needed for the encryption process.

JWE Ciphertext

Encrypted payload.

JWE Authentication Tag

Computed during the encryption process and used to verify integrity.

Token Generation

There are many libraries for many programming languages to work with JWE tokens. Let's consider as an example the Nimbus library.

build.gradle:

 
implementation 'com.nimbusds:nimbus-jose-jwt:9.25.6'


The payload can be represented as a set of claims:

 
{
    "sub": "alice",
    "iss": "https://idp.example.org",
    "exp": 1669541629,
    "iat": 1669541029
}


Let's generate a header:

Java
 
JWEHeader header = new JWEHeader(
    JWEAlgorithm.RSA_OAEP_256,
    EncryptionMethod.A256GCM
);


which corresponds to the following JSON:

 
{
    "enc": "A256GCM",
    "alg": "RSA-OAEP-256"
}


Let's generate an RSA key:

Java
 
RSAKey rsaJwk = new RSAKeyGenerator(2048)
    .generate();


Using the public part of the key, we can create an Encrypter object, with which we encrypt the JWT:

Java
 
RSAEncrypter encrypter = new RSAEncrypter(rsaJwk.toRSAPublicKey());

EncryptedJWT jwt = new EncryptedJWT(header, jwtClaims);
String jweString = jwt.encrypt(encrypter);


Execution result:

 
eyJlbmMiOiJBMjU2R0NNIiwiYWxnIjoiUlNBLU9BRVAtMjU2In0.O01BFr_XxGzKEUb_Z9vQOW3DX2cQFxojrRy2JyM5_nqKnrpAa0rvcPI_ViT2PdPRogBwjHGRDM2uNLd1BberKQlaZYuqPGXnpzDQjosF0tQlgdtY3uEZUMT-9WPP8jCxxQg0AGIm4abkp1cgzAWBQzm1QYL8fwaz16MS48ExRz41dLhA0aEWE4e7TYzjrfaK8M4wIUlQCFIl-wS1N3U8W2XeUc9MLYGmHft_Rd9KJs1c-9KKdUQf6tEzJ92TGEC7TRZX4hGdtszIq3GGGBQaW8P9jPozqaDdrikF18D0btRHNf3_57sR_CPEGYX0O4mY775CLWqB4Y1adNn-fZ0xoA.ln7IYZDF9TdBIK6i.ZhQ3Q5TY827KFQw8DdRRzQVJVFdIE03B6AxMNZ1sQIjlUB4QUxg-UYqjPJESPUmFsODeshGWLa5t4tUri5j6uC4mFDbkbemPmNKIQiY5m8yc.5KKhrggMRm7ydVRQKJaT0g


To decode a JWE token, you need to create a Decryptor object and pass to it the private part of the key:

Java
 
EncryptedJWT jwt = EncryptedJWT.parse(jweString);
RSADecrypter decrypter = new RSADecrypter(rsaJwk.toPrivateKey());

jwt.decrypt(decrypter);
Payload payload = jwt.getPayload();


Here, we used an asymmetric encryption algorithm — the public part of the key is used for encryption, and the private part for decryption. This approach allows issuing JWE tokens for third-party services and being sure that the data will be protected (when there are intermediaries in the token transmission path). In this case, the final service needs to publish the public keys, which we will use to encrypt the content of the token. To decrypt the token the service will use the private part of the key, which it will keep secret.

Authentication/Authorization service

But what if we have the same Issuer and Consumer token service? It could be a backend that sets a cookie in the user's browser with sensitive information. In that case, you don't need to use an asymmetric algorithm — you can use a symmetric algorithm. In JWE terms, this is direct encryption.

JWE token

Java
 
JWEHeader header = new JWEHeader(JWEAlgorithm.DIR, EncryptionMethod.A128CBC_HS256);


which corresponds to the following JSON:

 
{
  "enc": "A128CBC-HS256",
  "alg": "dir"
}


Let's generate a 256-bit key:

Java
 
KeyGenerator keyGen = KeyGenerator.getInstance("AES");
keyGen.init(256);
SecretKey key = keyGen.generateKey();


and encrypt JWT:

Java
 
JWEObject jweObject = new JWEObject(header, jwtClaims.toPayload());
jweObject.encrypt(new DirectEncrypter(key));
String jweString = jweObject.serialize()


Execution Result:

 
eyJlbmMiOiJBMTI4Q0JDLUhTMjU2IiwiYWxnIjoiZGlyIn0..lyJ_pcHfp8cz13TVav8MZQ.LmeN4jHxYg-dEFZ98PlVfNXFI29L5NGanA6ncALWcI9uDqpoXaaBcKeOKuzRayfQ3X7yPTuiMRHAUHMR5K3Rucmb8fQw2dkP3EONUg0lbdbmfbNwDbjQcWCGUWXfBWFg.v63pTlB7B15ZLEwSBwBUAg


Note that direct encryption does not include the JWE Encrypted Key part of the token.

To decrypt the token, you need to create a Decryptor from the same key:

Java
 
EncryptedJWT jwt = EncryptedJWT.parse(jweString);
jwt.decrypt(new DirectDecrypter(key));

Payload payload = jwt.getPayload();


Performance

To evaluate the performance of symmetric and asymmetric encryption algorithms, a benchmark was conducted using the JHM library. RSA_OAEP_256/A256GCM was chosen as the asymmetric algorithm, A128CBC_HS256 as the symmetric algorithm. The tests were run on a Macbook Air M1.

The payload:

 
{
  "iss": "https://idp.example.org",
  "sub": "alice",
  "exp": 1669546229,
  "iat": 1669545629
}


Benchmark results:

 
Benchmark                Mode  Cnt       Score      Error  Units
Asymmetric Decrypt      thrpt    4    1062,387 ±    4,990  ops/s
Asymmetric Encrypt      thrpt    4   17551,393 ±  388,733  ops/s
Symmetric Decrypt       thrpt    4  152900,578 ± 1251,034  ops/s
Symmetric Encrypt       thrpt    4  122104,824 ± 5102,629  ops/s

Asymmetric Decrypt       avgt    4       0,001 ±    0,001   s/op
Asymmetric Encrypt       avgt    4      ≈ 10⁻⁴              s/op
Symmetric Decrypt        avgt    4      ≈ 10⁻⁵              s/op
Symmetric Encrypt        avgt    4      ≈ 10⁻⁵              s/op


As expected, asymmetric algorithms are slower. According to the test results, more than ten times slower. Thus, if possible, symmetric algorithms should be preferred to increase performance.

Conclusion

JWE tokens are quite a powerful tool and allow you to solve problems related to secure data transfer while taking all the benefits of self-contained tokens. At the same time, it is necessary to pay attention to performance issues and choose the most appropriate algorithm and key length.

JSON Algorithm Java (programming language) JWT (JSON Web Token)

Opinions expressed by DZone contributors are their own.

Related

  • Floyd's Cycle Algorithm for Fraud Detection in Java Systems
  • Introduction to Polymorphism With Database Engines in NoSQL Using Jakarta NoSQL
  • JSON Handling With GSON in Java With OOP Essence
  • Proper Java Exception Handling

Partner Resources

×

Comments
Oops! Something Went Wrong

The likes didn't load as expected. Please refresh the page and try again.

ABOUT US

  • About DZone
  • Support and feedback
  • Community research
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Core Program
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 3343 Perimeter Hill Drive
  • Suite 100
  • Nashville, TN 37211
  • support@dzone.com

Let's be friends:

Likes
There are no likes...yet! 👀
Be the first to like this post!
It looks like you're not logged in.
Sign in to see who liked this post!