Always getting invalid signature in jwt.io
Asked Answered
N

6

39

I always get invalid signature when I input the generated token in jwt.io Here is my code for making the token

const secret = 'secret';
const token = jwt.sign({
    username: user.username,
    userID: user._id
  },
  secret, {
    expiresIn: "1hr"
  }
);

What did I do wrong?

I'm using the jsonwebtoken package. https://github.com/auth0/node-jsonwebtoken

Natatory answered 9/6, 2018 at 13:27 Comment(2)
Which package u r using for jwt?Ike
I'm using the jsonwebtoken package. github.com/auth0/node-jsonwebtokenNatatory
I
20

If you are using jsonwebtoken lib, I tried and able to create the token and verify as well. Please have a look at the code and let me know in comments if you are still facing the issue.

var jwt = require('jsonwebtoken')

const secret = 'secret';
const token = jwt.sign({
        username: "",
        userID: 1
    },
    secret, {
        expiresIn: "1hr"
    },
    function(err, token) {
        if (err) {
            console.log(err);
        } else {
            console.log(token);
        }
    });

Here is the link of jwt.io where I entered your secret used and it's saying verified.

https://jwt.io/#debugger-io?token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6IiIsInVzZXJJRCI6MSwiaWF0IjoxNTI4NTUyMDYyLCJleHAiOjE1Mjg1NTU2NjJ9.raL79zTGONyXgr9vuXzAyMflHJ0JqPYTXsy9KwmlXhA

enter image description here

Ike answered 9/6, 2018 at 13:51 Comment(4)
Actually the signature is invalid if you click the link. However, I could make it work with the npm package. Is maybe jwt.io broken in some way?Waterbuck
@SteffenT Click on the checkbox thereIke
Late to the party, but the site updates the JWT you pasted when you change the secret. So, you have to paste the secret first, then the JWT.Porkpie
@Porkpie that's correct, but very often people use jwt.io the wrong way and don't notice the updated signature and just think they verified the token. I described the correct usage in my answer hereSovran
M
36

TL_DR:

Extract the first key from the keys array in the JSON returned by the https://example.com/.well-known/jwks, and paste it in the first textbox of VERIFY SIGNATURE section of jwt.io page. Of course, example.com is the domain where you hosted your OpenIddict auth server. Could also be something like https://example.com/my/auth/server/. jwt.io interface

The whole story:

When you paste the JWT in jwt.io, it does this:

  1. decodes the token, and shows the header and the payload on the right
  2. tries to validate the signature

If the step 1. fails to decode the payload, that's because the token is encoded. To solve this problem, modify the OpenIddict config by adding .DisableAccessTokenEncryption();

The step 2, signature validation, is done by getting the issuer iss field from the PAYLOAD section: enter image description here

and uses it as the base URI to invoke the /.well-known/openid-configuration, which includes the JWKS uri, which looks like "jwks_uri": "https://example.com/.well-known/jwks"

jwt.io can fail to get this data for example:

  • if you're testing in https://localhost, which isn't accessible from internet, just like the https://localhost:5001 of this example
  • because the request is rejected by any other reason (unknown domain, firewall...)

If this is the case, there is an option to solve the problem: paste the appropriate string in the upper textbox of VERIFY SIGNATURE section, which has this placeholder:

Public key in SPKI, PKCS #1, X.509 certificate, or JWK string format.

What is the right string to paste there? It's easy if you take into account 2 details:

  1. you can get the JSON with this info from the aforementioned https://example.com/.well-known/jwks endpoint
  2. the info returned is a JWKS string, but a JWK is required.

So, invoke the enpoint, get the JWKS which looks like this:

{
  "keys": [
    {
      "kid": "2727AC6EB83977...",
      "use": "sig",
      "kty": "RSA",
      "alg": "RS256",
      "e": "AQAB",
      "n": "6tSSW3rz53Xj3w...",
      "x5t": "Jyesbrg5d_2M...",
      "x5c": [
        "MIIC9TCCAd2gAwIBAgIJAKL..."
      ]
    }
  ]
}

and extract the JWK which is simply the first entry in the "keys" array, i.e

{
  "kid": "2727AC6EB83977...",
  "use": "sig",
  "kty": "RSA",
  "alg": "RS256",
  "e": "AQAB",
  "n": "6tSSW3rz53Xj3w...",
  "x5t": "Jyesbrg5d_2M...",
  "x5c": [
        "MIIC9TCCAd2gAwIBAgIJAKL..."
   ]
}

Paste this value in the textbox, and you'll get the blue "Signature verified" message, as you can see at the bottom of the first snapshot.

NOTE: depending on the configuration (AddEphemeralSigningKey(), AddDevelopmentSigningCertificate(), etc.), the JWKS keys can have more or less properties, but it should work anyway.

Melamie answered 31/12, 2021 at 2:8 Comment(0)
I
20

If you are using jsonwebtoken lib, I tried and able to create the token and verify as well. Please have a look at the code and let me know in comments if you are still facing the issue.

var jwt = require('jsonwebtoken')

const secret = 'secret';
const token = jwt.sign({
        username: "",
        userID: 1
    },
    secret, {
        expiresIn: "1hr"
    },
    function(err, token) {
        if (err) {
            console.log(err);
        } else {
            console.log(token);
        }
    });

Here is the link of jwt.io where I entered your secret used and it's saying verified.

https://jwt.io/#debugger-io?token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6IiIsInVzZXJJRCI6MSwiaWF0IjoxNTI4NTUyMDYyLCJleHAiOjE1Mjg1NTU2NjJ9.raL79zTGONyXgr9vuXzAyMflHJ0JqPYTXsy9KwmlXhA

enter image description here

Ike answered 9/6, 2018 at 13:51 Comment(4)
Actually the signature is invalid if you click the link. However, I could make it work with the npm package. Is maybe jwt.io broken in some way?Waterbuck
@SteffenT Click on the checkbox thereIke
Late to the party, but the site updates the JWT you pasted when you change the secret. So, you have to paste the secret first, then the JWT.Porkpie
@Porkpie that's correct, but very often people use jwt.io the wrong way and don't notice the updated signature and just think they verified the token. I described the correct usage in my answer hereSovran
E
6

In my case, I forgot to put my secret keys in "VERIFY SIGNATURE" (Right hand side, after "HEADER" and "PAYLOAD" boxes). Empty secret key in jwt.io doesn't show any error to user as of May 2023, while checking their token validation - most users get this error of Invalid Signature. Make sure to put the secret key string after:

HMACSHA256( base64UrlEncode(header) + "." + base64UrlEncode(payload), enter_here_your_secret_key)

Add secret key

JWT.IO

Exotoxin answered 11/5, 2022 at 6:58 Comment(0)
M
0

i had a similar problem like that, i later found out that i was using the wrong secret

Make sure you are using the correct secret

Menefee answered 30/9, 2021 at 17:56 Comment(1)
Your answer could be improved with additional supporting information. Please edit to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers in the help center.Nonalcoholic
A
0

In my case, jwt.io was failing to retrieve my public keys (as described above) because my server wasn't returning CORS headers to allow a frontend JavaScript app like jwt.io to access the proper endpoints.

Asthmatic answered 31/5, 2023 at 1:7 Comment(0)
T
-2

I had the same problem. I fixed it or verified after clicking on the checkbox "secret base64 encoded" inside the "Verify Signature" panel.

Talanian answered 15/1, 2022 at 17:29 Comment(1)
No, with clicking on the checkbox "secret base64 encoded" you do not verify the token. In your screenshot, there's not even a secret pasted to the input field. Clicking on the checkbox just causes a recalculation of the signature, which is then automatically verified. Please read my answer here to see what actually happens and how you use jwt.io in a correct way.Sovran

© 2022 - 2024 — McMap. All rights reserved.