Skip to content

Lax JWK Decoding Issue #591

@madaster97

Description

@madaster97

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions