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

JWT decryption does not support IVs longer than encryption key length for GCM #678

Closed
2 tasks done
twwildey opened this issue May 25, 2024 · 9 comments
Closed
2 tasks done

Comments

@twwildey
Copy link

twwildey commented May 25, 2024

What happened?

The decrypt method under src/runtime/node/decrypt.js invokes checkIvfLength, which assumes the byte length of the IV must be the byte length of the encryption key. While this may be required for many block cipher modes, it is not required for GCM. This same issue was officially fixed by Node.js back in v6: nodejs/node#6376

As such, jose should be updated to support IVs that are longer than encrypted key when operating with GCM block ciphers. This issue prevents encrypted JWTs produced by python-jose from being decrypted by the jose NPM module.

This is actively blocking the development of a Sublime Text plugin to interface with the LSP services for AWS Q Developer.

Version

5.3.0

Runtime

Node.js

Runtime Details

Node 18.18.1

Code to reproduce

I've confirmed that commenting out the checkIvfLength invocation in the decrypt method within src/runtime/node/decrypt.js successfully decrypts a JWT using A256GCM encryption and the dir algorithm.

My integration testing used the decodeCredentialsRequestToken method in aws/language-server-runtimes, which successfully decrypts a JWT using A256GCM encryption and the dir algorithm once the checkIvfLength invocation is commented out in the decrypted method.

Required

  • I have searched the issues tracker and discussions for similar topics and couldn't find anything related.
  • I agree to follow this project's Code of Conduct
@panva
Copy link
Owner

panva commented May 25, 2024

which assumes the byte length of the IV must be the byte length of the encryption key

That is not what the method is doing. GCM by the JOSE spec requires 96bit iv. That's what is checked to be used. See the JWA RFC

We've identitied and reported the issue of using non-conform iv lengths in python-jose already - mpdavis/python-jose#281

@panva panva closed this as not planned Won't fix, can't repro, duplicate, stale May 25, 2024
@panva panva removed the triage label May 25, 2024
@twwildey
Copy link
Author

Understood. I did not consult the JWA spec, but if it requires 96 bits for the IV in AES-GCM modes, then it does seem that python-jose should be updated instead.

Simultaneously, I do not see how longer IVs would compromise the security of symmetric block ciphers in GCM mode. It seems that longer IVs could only increase their entropy, which would improve the security posture. Is it truly that critical for python-jose to resolve this on their side, or could jose allow 96+ bits for IVs in the AES-GCM modes?

@panva
Copy link
Owner

panva commented May 27, 2024

Simultaneously, I do not see how longer IVs would compromise the security of symmetric block ciphers in GCM mode. It seems that longer IVs could only increase their entropy, which would improve the security posture.

That is not universally the case https://crypto.stackexchange.com/questions/41601/aes-gcm-recommended-iv-size-why-12-bytes

could jose allow 96+ bits for IVs in the AES-GCM modes?

If the specification allowed such. It does not.

@Shakeskeyboarde
Copy link
Sponsor

Sure, it makes sense for Jose encryption to be strict. But, it seems like decryption could relax on the spec for better compatibility with encryption sources that are not as strict as Jose.

Encrypting is where the spec and security are critical. Decryption should work if technically possible.

@panva
Copy link
Owner

panva commented May 27, 2024

Sure, it makes sense for Jose encryption to be strict. But, it seems like decryption could relax on the spec for better compatibility with encryption sources that are not as strict as Jose.

Encrypting is where the spec and security are critical. Decryption should work if technically possible.

Hi @Shakeskeyboarde

That's just not how interoperability is achieved, nor is it the spirit which the specifications are written with.
A single actor that doesn't follow the specified parameters does not warrant an ecosystem wide change. Other javascript modules also check for IV length to be 12 byte and of course non-javascript projects do as well, e.g. nimbus.

@twwildey
Copy link
Author

Having read through the following resources for GCM and GHASH:

  1. https://en.wikipedia.org/wiki/Galois/Counter_Mode
  2. https://nvlpubs.nist.gov/nistpubs/Legacy/SP/nistspecialpublication800-38d.pdf
  3. https://www.iacr.org/archive/fse2012/75490220/75490220.pdf

The argument that a longer IV bit string increases the likelihood of collision requires that GHASH results in collisions for distinct input values or that the hashed values are not "evenly" spaced compared to the 96 bit length IV (i.e. different IVs are spaced 2^32).

The AES key determines the subgroup of GF(2^128) that's used during polynomial multiplication in GHASH for GCM. If the key used for the computation is not a weak key, then the subgroup size - ord(H) - can be confirmed to be above or near 2^96, where ord(H) is the order of the multiplicative subgroup corresponding to the AES key represented by H.

Since all inputs to GHASH are multiplied by H, all IVs of the same length are guaranteed to be spaced by intervals of (2^128 - 1) / ord(H) for the same key. 96 bit length for IVs provides the "best guarantee" that the spacings will be 2^32, since the spacing is effectively determined by ord(H).

For a given AES key, the IV for each message should support up to 2^32 encrypted blocks without risk of collision. More so, the counters used for encryption blocks across different message should never collide. Using a 96 bit IV annihilates the possibility for collision across messages in GCM, since GHASH is not used. More so, when the ord(H) is not exactly 2^96, then spacings are not guaranteed to be 2^32.

twwildey added a commit to twwildey/python-jose that referenced this issue May 29, 2024
… block cipher mode to adhere to the RFC for JWA in `jose/backends/cryptography_backend.py`

See https://www.rfc-editor.org/rfc/rfc7518.html#section-5.3 for the official RFC requirements for JWA

See panva/jose#678 for related discussion on this issue
twwildey added a commit to twwildey/python-jose that referenced this issue May 30, 2024
… block cipher mode to adhere to the RFC for JWA in `jose/backends/cryptography_backend.py`

See https://www.rfc-editor.org/rfc/rfc7518.html#section-5.3 for the official RFC requirements for JWA

See panva/jose#678 for related discussion on this issue
twwildey added a commit to twwildey/python-jose that referenced this issue May 30, 2024
… block cipher mode to adhere to the RFC for JWA in `jose/backends/cryptography_backend.py`

See https://www.rfc-editor.org/rfc/rfc7518.html#section-5.3 for the official RFC requirements for JWA

See panva/jose#678 for related discussion on this issue
twwildey added a commit to twwildey/python-jose that referenced this issue May 30, 2024
… block cipher mode to adhere to the RFC for JWA in `jose/backends/cryptography_backend.py`

See https://www.rfc-editor.org/rfc/rfc7518.html#section-5.3 for the official RFC requirements for JWA

See panva/jose#678 for related discussion on this issue
twwildey added a commit to mpdavis/python-jose that referenced this issue May 30, 2024
… block cipher mode to adhere to the RFC for JWA in `jose/backends/cryptography_backend.py`

See https://www.rfc-editor.org/rfc/rfc7518.html#section-5.3 for the official RFC requirements for JWA

See panva/jose#678 for related discussion on this issue
@twwildey
Copy link
Author

I have merged the following PR in python-jose to address this issue: mpdavis/python-jose#355

@twwildey
Copy link
Author

I have merged the following PR in python-jose which fixes test failures that were blocking the distribution of these changes to PyPI: mpdavis/python-jose#356

@twwildey
Copy link
Author

I see that python-jose has effectively been abandoned for https://jose.authlib.org/en/

I will be migrating my project to use https://jose.authlib.org/en/ instead.

@github-actions github-actions bot locked and limited conversation to collaborators Sep 2, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants