In an asymmetric algorithm, a JWT token is signed with an Identity Provider’s private key. To verify the signature of the token, one will need to have a matching public key. This post will cover how to use the JWT tool at to verify the signature of an signed Azure AD token (either access or id token).


  • You should only validate the token intended for your own resource.  Using the technique below to validate the signature of a Microsoft First Party Apps token (for example token audience is for Microsoft Graph resource) may fail.
  • utility is a 3rd party tool.  We (Microsoft) have no knowledge of how this site utilizes the token information.
  • To see the token claim information, we recommend using the Microsoft utility since the site does not cache token information.

Verifying the token signature

  1. Browse to and paste the JWT token into Encoded text box. The tool should automatically detect the token’s signature algorithm (RS256) and displays the token into 3 parts: header, payload, and signature. Note the “kid” field in the header. This is the key id of the certificate used to sign the token

    Scrolling down a little you will see the version of the token (v1 token in this case) and it will say “invalid signature”. This is expected since at this point we have not provided any certificate info for the tool to verify the token signature.

  2. Find the jwks URL info from Azure AD’s OIDC well-known endpoint. Depending upon your token version, use the correct well known endpoint (make sure to supply the correct tenant name in the well known URL):

    V1 token:{tenant name}/.well-known/openid-configuration

    V2 token:{tenant name}/v2.0/.well-known/openid-configuration

    For my case, I use the V1 OIDC endpoint. You can either paste the URL into a web browser or postman to find the “jwks_uri” field from the response:

  3. From the JWKS URI endpoint, find the key that has a matching kid (key id) as the token. Copy the long text string from the key’s x5c field. This is the public key section

  4. Enclose the x5c string in the BEGIN CERTIFICATE / END CERTIFICATE block as followed (see example at the end post)



    ‑‑‑‑‑END CERTIFICATE‑‑‑‑‑

  5. Now copy entire text above into the 1st textbox under “Verify Signature” section and the Invalid Signature text should change to “Signature Verified”



The above steps show a manual way to validate the JWT token’s signature given the certificate’s public key.


for clarity:

Example public certificate section

5 dashes followed (no space) by BEGIN CERTIFICATE followed by 5 dashes. The end section is in the same format

0 0 votes
Article Rating
Notify of
Newest Most Voted
Inline Feedbacks
View all comments
July 13, 2020 11:24 am

if I don’t find the kid in<tenantId>/discovery/v2.0/keys, what can be the reason? I’m using AAD b2c, in case this makes a difference.

July 13, 2020 11:46 am

aha, for B2C, one has to use

to get the config and then from there to the keys discovery

chris ondrovic
chris ondrovic
August 22, 2020 8:16 pm

any idea how to get it validate tokens with the audience of Seems like it always returns invlaid signature

October 26, 2020 5:37 am

Hello, Do we have a java API to validate the token signature. in Our scenario , we have a mobil app calling java web app. The mobil app will pass the token to java web app , and we want to validate the token signature.

Also, do we have an example of a mobil app calling a Java web app and passing thr toke. I want to understand how to register both apps and the flow to use ( Like we have auth code flow – want to know which flow can be used in this scenario)

January 23, 2021 5:42 pm

I have an access_token with issuer, and ver: 1.0, but I still cannot validate it with the corresponding x5c from its kid. I also realized that both of the jwks_uri from the Azure’s OIDC well-known endpoints give us the exact same public keys, with the only difference being that the version 2 has the issuer property; the rest stays the same. That being said, how to validate v1 token? Is there something I missed?

January 24, 2021 8:17 pm

I do get a token after signing myself in (implicit flow), but how do I make sure that the access_token is for my own API?

Mark B.
Mark B.
March 16, 2021 10:57 am

I’m adding your X5C key surrounded with the BEGIN/END CERTIFICATE lines into the and see that this certificate is invalid.
I also try to do the same with other certificates from – all of them appear invalid.
If I try to validate signature by “jsonwebtoken” library:

jwt.verify(access_token, pubcert, function(err, decoded) {
    console.log( // bar

with Microsoft Graph API access_token and pubcert created like explained in this article I receive an error:
error:0909006C:PEM routines:get_name:no start line