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

Lax JWK Decoding Issue #591

Open
madaster97 opened this issue Jul 18, 2023 · 2 comments
Open

Lax JWK Decoding Issue #591

madaster97 opened this issue Jul 18, 2023 · 2 comments

Comments

@madaster97
Copy link

Hi there,

If you format an RSA JWK in a slightly incorrect way, this tool will still count it as valid for validating JWTs. However, other tools such as JWT.IO and Microsoft libraries do not count these keys as correct, so using this tool can cause compatibility issues.

Details:

  • Invalid public key (JWT.IO doesn't accept this, and neither do several libraries I tested):
    {
      "kty": "RSA",
      "e": "AQAB",
      "use": "sig",
      "kid": "jwk-rsa",
      "n": "AKLMe2qRcXdeqtYEiA5Cv64eA3TOI_eoZbwoyl20E-skY4gCExE3BBugEdyFaKiopGVczSIQJwlzI2-mJYwMBz8iDsAx913E2it84LjTELP-9D5F1N9R50eH76raBq0SxfIx-vL0mVFX7o9A6032lnwMLI3Dhj2HxGD7ZVvaj7l2mypPA2zad6JkcS6XSugI-lXxWtTHln4FxtvG7kjEpBQtjZXcsJgU-wsxdxPRIxCtm0aznSogjHgrtSuD4nsN6OAiWz154JUCq0WcB6VBMR-LaH68iSWpAjyv4sMvEVXkOOr-vqXMAhsYedKWF2496bHUhDtGMqILqprqbed3Rz0="
    }
  • Correctly formatted version of key above (I converted to PEM and then back to JWK using the JOSE library, so seems like an encoding issue):
    {
      "kty": "RSA",
      "e": "AQAB",
      "use": "sig",
      "kid": "jwk-rsa",
      "n": "osx7apFxd16q1gSIDkK_rh4DdM4j96hlvCjKXbQT6yRjiAITETcEG6AR3IVoqKikZVzNIhAnCXMjb6YljAwHPyIOwDH3XcTaK3zguNMQs_70PkXU31HnR4fvqtoGrRLF8jH68vSZUVfuj0DrTfaWfAwsjcOGPYfEYPtlW9qPuXabKk8DbNp3omRxLpdK6Aj6VfFa1MeWfgXG28buSMSkFC2NldywmBT7CzF3E9EjEK2bRrOdKiCMeCu1K4Piew3o4CJbPXnglQKrRZwHpUExH4tofryJJakCPK_iwy8RVeQ46v6-pcwCGxh50pYXbj3psdSEO0Yyoguqmupt53dHPQ"
    }
  • Example JWT: see JWT.IO link below

To start, JWT.IO does not like the invalid public key.

However, rsasignjs count this key as valid:

const KJUR = require("jsrsasign");

const jwt = "eyJraWQiOiJqd2stcnNhIiwiYWxnIjoiUlMyNTYifQ.eyJzdWIiOiIwMTRmZjNmYy1jN2Y3LTQwZmYtOWEyYy1hZTlmMDNiNzljNDIiLCJhdWQiOiJodHRwczpcL1wvZXBpY3Byb3h5LW5wLmV0MDkxNS5lcGljaG9zdGVkLmNvbVwvRkhJUlByb3h5UE9DXC9vYXV0aDJcL3Rva2VuIiwiaXNzIjoiMDE0ZmYzZmMtYzdmNy00MGZmLTlhMmMtYWU5ZjAzYjc5YzQyIiwiZXhwIjoxNjg5Njg2OTc0LCJpYXQiOjE2ODk2ODY5MTQsImp0aSI6IjQ3ZDhhZjUxLTRjMjItNDA2MS04NmIzLWRlMmJhM2I5OTY0YSJ9.DO1jA1MgRvLvgKfxzSU2vZ7Xyv9Dh455gjNHrywyY2-I93iYqoRtYsB6IcocCGn_HXEqNKEWVWCNOnt834nipf50FNDRorD_zW-KOQ4Le8u82XPZyc0nqGb7cwNtPgMjpRFG-IH44AT4scScfhYRzKD7BWnLEzH3kfY1iPdcWvbPbPFgvJDsI2-nmPSGx7b5wSr8NH9xcYJD0jFhTVy-nl-zIXqE83-1ycqg7ufCxRWXyCI8sDR6jzytmg75X1hdZsJty1LQRWuZ3rD1RhofzypD8SpVQz5HZ2-xHjZGZDgokEaKqwu2M2qaKX0I6PNILmMJ4WVeIfWnF-3c68qwXw"
const key = KJUR.KEYUTIL.getKey({
  "kty": "RSA",
  "e": "AQAB",
  "use": "sig",
  "kid": "jwk-rsa",
  "n": "AKLMe2qRcXdeqtYEiA5Cv64eA3TOI_eoZbwoyl20E-skY4gCExE3BBugEdyFaKiopGVczSIQJwlzI2-mJYwMBz8iDsAx913E2it84LjTELP-9D5F1N9R50eH76raBq0SxfIx-vL0mVFX7o9A6032lnwMLI3Dhj2HxGD7ZVvaj7l2mypPA2zad6JkcS6XSugI-lXxWtTHln4FxtvG7kjEpBQtjZXcsJgU-wsxdxPRIxCtm0aznSogjHgrtSuD4nsN6OAiWz154JUCq0WcB6VBMR-LaH68iSWpAjyv4sMvEVXkOOr-vqXMAhsYedKWF2496bHUhDtGMqILqprqbed3Rz0="
})
const sigValid = KJUR.jws.JWS.verify(jwt, key);

console.log(sigValid) // should be false, but is true

Can you tell where the inconsistency is coming from? I've run into something like this before, and it could be because of missing padding on the raw "n" field of the keys.

@madaster97
Copy link
Author

For reference, here's the script I used to convert the "wrong" form of the public key into the right form, using JOSE v4.11.1:

const jose = require('jose');
(async () => {
    const key = await jose.importJWK({
        "kty": "RSA",
        "e": "AQAB",
        "use": "sig",
        "kid": "jwk-rsa",
        "n": "AKLMe2qRcXdeqtYEiA5Cv64eA3TOI_eoZbwoyl20E-skY4gCExE3BBugEdyFaKiopGVczSIQJwlzI2-mJYwMBz8iDsAx913E2it84LjTELP-9D5F1N9R50eH76raBq0SxfIx-vL0mVFX7o9A6032lnwMLI3Dhj2HxGD7ZVvaj7l2mypPA2zad6JkcS6XSugI-lXxWtTHln4FxtvG7kjEpBQtjZXcsJgU-wsxdxPRIxCtm0aznSogjHgrtSuD4nsN6OAiWz154JUCq0WcB6VBMR-LaH68iSWpAjyv4sMvEVXkOOr-vqXMAhsYedKWF2496bHUhDtGMqILqprqbed3Rz0="
    }, "RS256");
    const pub = await jose.exportSPKI(key);
    console.log(pub);

    const jwkPub = await jose.exportJWK(key);
    console.log(JSON.stringify(jwkPub,null,2));
})();

@kjur
Copy link
Owner

kjur commented Mar 27, 2024

Hi @madaster97 , I got the issue.
The n of wrong form has leading zero for two's supplement.

AKLMe2qRcXdeqt...
=>
00a2cc7b6a9171775... (in hexadecimal)

osx7apFxd16q1gSIDkK...
=>
  a2cc7b6a9171775...

I'll fix the issue.

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

No branches or pull requests

2 participants