Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Created JSON Web Encryption Cheat Sheet #1613

Draft
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

caffeine-rohit
Copy link
Contributor

This PR closes #1225 .
This is the draft of the JSON Web Encryption (JWE) Cheat Sheet for the OWASP Cheat Sheet Series.

🔹 Key Highlights:

  • 📌 Introduction to JWE: Explains its structure, use cases, and differences from JWT.
  • 🔐 Choosing Secure Encryption Algorithms: Covers AES-GCM, ECDH-ES, RSA-OAEP, and PBES2 with best practices.
  • 🛡 Implementation Guidelines: Provides secure encryption and decryption examples in Python & Java.
  • Security Best Practices:
    • Validation of alg and enc headers to prevent header manipulation.
    • Proper key management, avoiding nonce/IV reuse, and ensuring AEAD encryption.
    • Secure storage recommendations (avoid localStorage/sessionStorage).
    • Protection against replay attacks, token expiration policies, and TLS/SSL enforcement.
  • Common Pitfalls to Avoid: Covers weak algorithm risks, improper key handling, and compression vulnerabilities.
  • 🔄 JWE vs JWS & JWT: Explains when to use each and how to combine JWE with JWS for integrity & confidentiality.

This draft follows OWASP ASVS cryptography best practices and aims to provide developers with a structured guide for securely implementing JWE.

Looking forward to feedback and improvements! 🚀

This PR closes OWASP#1225 .
This is the draft of the JSON Web Encryption (JWE) Cheat Sheet for the OWASP Cheat Sheet Series.

### 🔹 Key Highlights:
- 📌 **Introduction to JWE**: Explains its structure, use cases, and differences from JWT.
- 🔐 **Choosing Secure Encryption Algorithms**: Covers AES-GCM, ECDH-ES, RSA-OAEP, and PBES2 with best practices.
- 🛡 **Implementation Guidelines**: Provides secure encryption and decryption examples in Python & Java.
- ⚠ **Security Best Practices**:
  - Validation of `alg` and `enc` headers to prevent header manipulation.
  - Proper key management, avoiding nonce/IV reuse, and ensuring AEAD encryption.
  - Secure storage recommendations (avoid localStorage/sessionStorage).
  - Protection against replay attacks, token expiration policies, and TLS/SSL enforcement.
- ⚡ **Common Pitfalls to Avoid**: Covers weak algorithm risks, improper key handling, and compression vulnerabilities.
- 🔄 **JWE vs JWS & JWT**: Explains when to use each and how to combine JWE with JWS for integrity & confidentiality.

This draft follows OWASP ASVS cryptography best practices and aims to provide developers with a structured guide for securely implementing JWE.

Looking forward to feedback and improvements! 🚀
Copy link
Contributor

@raphaelahrens raphaelahrens left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

First of all thanks you for all the work.

Since JWE is a good gun for hitting ones foot I would like so see a handful of configurations which are secure and then later explain why deviations from these are problematic.
But I also see that JWE is very flexible and can be used in many scenarios and it would be difficult to find good configurations for every use case.

Overall this is a good start, but since JWE is complex I assume this will need some iterations to become useful for a developer.

Some applications use JWTs only with JWE (encryption) without signing them using JWS. While this approach ensures confidentiality, it introduces potential risks:

**Problem:** Since there’s no digital signature (JWS), the recipient cannot verify the sender’s authenticity.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would add that when using JWE there needs to be a key management concept already, since JWE assumes an asymmetric or symertric key has already been shared between communications partners.
Maybe just a note and a link to the key management CS


- If integrity verification is required. Without a JWS, attackers might swap encrypted tokens without detection.

- If you rely on public-key encryption, ensure that only trusted issuers can create encrypted tokens.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is this a reason not to use JWE?
Since the text mentions I can use it when I can ensure only trusted issuers can create encrypted tokens.
It would also be helpful to have direction on what to do instead.


- **Use Case:** Fast encryption for internal services where both sender and receiver share a secret.
- **Advantages:** High performance; efficient for high-throughput systems
- **Considerations:** Requires secure key distribution and rotation.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe rephrase this to

- **Considerations:**
     - Requires secure key distribution
     - **MUST** implement secure key rotation
     - Each IV can only be used once and **MUST** not be reused.

So the issue are better highlighted.
I also find the word considerations a bit weak since this can easily lead to full compromises.

- **Note on ECDH-ES:** When using it with key wrapping (e.g., ECDH-ES+A128KW), this method is particularly useful for multi-recipient JWEs.
- **Quantum Considerations:** ECDH-ES (like other ECC methods) might be vulnerable to quantum attacks in the future. Consider hybrid or post-quantum approaches if long-term security is a concern.
- **RSA-OAEP:** May be used in legacy systems or where RSA keys are already in place.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For RSA and ECDH there also needs to be a way to revoke keys.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Technically, unless you are constantly using ephemeral symmetric keys (which probably is not workable without a trusted KDE or asymmetric algs), you would need the ability to revoke symmetric keys as well as they can be compromised as well.


- **PBES2 (Password-Based Encryption):**
- **Use Case:** Only when a password-derived key is required.
- **Recommendation:** Avoid for system-level encryption if strong keys are available.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The PBKDF2 in PBES2 is not memory hard and should not be recommend when weak passwords are possible (which are difficult to exclude).
So I would not recommend this practice.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In general, I'd agree, but it depends in part on what your threat model is and where your risk tolerance lies. Argon2 would be better though, or even scrypt in a pinch. However, the problem with using "memory hard" algorithms is that they may not work well on low memory devices. YMMV.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The issue is that JWA only defines PBES2 so there is no Argon2.

But still I would not recommended password based jwe, without context, so it is not something for a cheat sheet.


# Example usage
# key should be 32 bytes for AES-256-GCM
```
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not use a library for python?

- **Fix:** Always set short expiration times and implement refresh tokens to prevent session fixation attacks.

- **Compressing data before encryption:** Compression can leak information (CRIME/BREACH attacks).

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would mention the zip header here.


### Symmetric vs. Asymmetric Encryption

- **Symmetric Encryption (e.g., AES-256-GCM):**
Copy link
Contributor

@raphaelahrens raphaelahrens Feb 11, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it talking about AES as an KEK with "alg": "A128GCMKW" or "alg": "dir" and AES as CEK?

In general this mess with alg and enc might require some explanation for just symmetric encryption.

| **Protection** | Uses digital signatures for integrity (but payload is visible) | Encrypts payload to ensure confidentiality |
| **Example Use Case**| Identity claims in OAuth | Protecting sensitive user data |

> **Note:** JWT ensures authenticity but does NOT encrypt data, while JWE provides full confidentiality.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note that confidentiality imply authenticity though. Both are needed. Does JWE support authenticated encryption?


Some applications use JWTs only with JWE (encryption) without signing them using JWS. While this approach ensures confidentiality, it introduces potential risks:

**Problem:** Since there’s no digital signature (JWS), the recipient cannot verify the sender’s authenticity.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It seems to me that you are confusing "sender's authenticity" with the "sender's identity" (which deals with the sender impersonation issue), But you can put the sender's encrypted blob as part of a JWT that ensures integrity (aka, authenticity) and if you trust the authenticated token, you normally should be willing to trust that encrypted blob and that it hasn't been tampered with. In other words, if the JWT claim is that it corresponds to Alice you have some reason to believe the encrypted blob is encrypted by Alice. It's not guaranteed by the same level of assurance that a dsig can provide, but even that is not foolproof unless you can ensure that the signing key that was used was actually Alice's private key and not (say) Mallory's. You either you have to full assurance that the corresponding public key that you think is Alice's actually belongs to Alice (and that her private key has not been compromised) or you need to be willing to trust some third party (e.g., an RA / CA who attests to the binding of Alice's identity and her public key.)

The bigger problem is you would have to use this very judiciously because of all the computational overhead. TANSTAAFL.


- If the decryption key is tightly controlled and only trusted parties can encrypt messages.

- If the payload itself includes authentication mechanisms, such as an HMAC inside the encrypted content, to verify sender authenticity.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note that HMACs are not equivalent to DSigs. HMAC keys may be shared and thus multiple parties may be able to "sign" the data. However, with DSigs, the general assumption is that the private (signing) key is kept private [may not be a correct assumption; it may have been compromised by malware, but the assumption is still there], so if the assumption is in fact true, only the holder of the private key can generate a signature.

| **Encrypted Key** | The symmetric key (Content Encryption Key or CEK) encrypted using a public key (if key wrapping is used). |
| **IV (Initialization Vector)** | A cryptographically secure random value ensuring uniqueness for encryption. |
| **Ciphertext** | The actual encrypted data (which includes the payload). |
| **Authentication Tag** | Provides integrity and authenticity (a result of AEAD encryption, e.g., AES-GCM). |
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

First of, in this context, integrity and authenticity are interchangable.

Secondly, while AES-GCM or AES-CCM, etc. can be used as AEAD, one needn't use that function; that's an optional piece, not mandatory. The AEAD portion itself is only important for the meta-data that is needed to ensure integrity. For example, the sender's email address or a X.509 SubjectDN, etc. that you can use to identify the sender. The data in this "authentication tag" is not encrypted, so it can't be anything sensitive.

Lastly, unless you can point to a specific standard, there is not enough information provided here for two developers implementing this to create two separate implementations that could securely interchange data. There's way more information that is needed here, so reference whatever standard that you have in mind.


**Final Recommendation:**

- Use **AES-256-GCM** for high-performance internal encryption when keys are securely managed.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"Keys are securely managed". Yeah; right. Key management is the single hardest problem in cryptography. You can't just hand wave over this. At a minimum, as @raphaelahrens noted in the comment https://github.com/OWASP/CheatSheetSeries/pull/1613/files#r1950482662, you at least need to reference the key management CS here.

Copy link
Collaborator

@kwwall kwwall left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I quit reading around line 115 or so in section 5. I have a lot of experience with applied cryptography (although none specifically with JWE), but even I would not rely on this draft CS to guide me. IMO, this needs a lot of work to make it coherent. I suggest that you start by getting a professional cryptographer to review it or someone who participated in some JWE standard. (There is a standard, right? Otherwise, STOP. RIGHT. NOW.)

This reminds me of someone who has captured a bunch of notes during a lecture and then is trying to regurgitate the information in some coherent format. This approach seems a bit scattershot to me and I find it very difficult to follow and I probably understand the underlying concepts better than most.

I am not approving this and am marking it as 'Request changes' but I am at a loss of what specific changes to request. I touched on some of them. And I am not dismissing your effort, but I think this is something that ultimately is too complex for a cheat sheet unless it is written to simply cal out details in some standard. And since you haven't referenced a standard, it's hard for me to know what to add.

I am willing to assist you, but it likely will have to wait until after the end of May because of things in my personal schedule. If you want to drop me an email we perhaps can arrange some time to talk. My biggest concern is that you are going to find all my feedback as negative, even though I don't intend it as that. I do not mean to discourage you. Your ambition to push your current boundaries, if anything, is something that we should all applaud.

I suggest rather than dumping this here, you put it up on Google Drive and then get a bunch of people to collaborate with you. Should you decide to do that, I may even be able to find a few people way more qualified than me to review it. (No promises, but I certainly can try.)

Best regards, -kevin

@mackowski
Copy link
Collaborator

I suggest rather than dumping this here, you put it up on Google Drive and then get a bunch of people to collaborate with you. Should you decide to do that, I may even be able to find a few people way more qualified than me to review it. (No promises, but I certainly can try.)

To be fair I told Rohit to create this PR for review and not use GD ;) Rohit created also Google Dock for this: https://docs.google.com/document/d/1Nsb3TUVLvHnFHRxmr9sm7eBDo6-lhUnK2wuzrOTA2OE/edit?usp=sharing
https://owasp.slack.com/archives/C073YNUQG/p1738686916585789

@mackowski
Copy link
Collaborator

I am fine in doing review in GD if that will be easier for this.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

New CS proposal: Javascript Object Signing and Encryption (JOSE)
4 participants