I get an access token from Microsoft Identity Platform and I try to verify its signature (to understand the process of validation) using jwt.io website. The thing is when I paste this access token on jwt.io website and paste the public key on the « public key » box, jwt.io is still returning an error, stating the signature is invalid. The public key I am using is given by Microsoft Identity using the « kid » claim. To be more precise I take the public key and wrap it with « ——BEGIN CERTIFICATE—- » and « —-END CERTIFICATE—- » and paste it all on the public key box. ( By the way, on the private key box I put nothing) What am I doing wrong ? Thank you for all your help.
-
1you can try without providing a key. Based on the information in the token, jwt.io might be able to find the public key on a JWKS endpoint on the azure site. See [Where does jwt.io get the public key from JWT token?](https://stackoverflow.com/q/64297228) to understand how it works. – jps Jul 03 '22 at 06:39
-
Which scopes did you use when acquiring the token? If you used MS Graph API scopes, this is expected. They use a different way for signing. Which doesn't matter to you as you should only be validating tokens meant for your API. – juunas Jul 03 '22 at 06:55
-
1@juunas thank you for your comment, but its a token for my web API (the audience claim is the client id of my web API), so I dont know what I am doing wrong – Idash Jul 03 '22 at 08:48
-
Thank you @jps for your answer but even if I dont put any keys, it still says « invalid signature »… – Idash Jul 03 '22 at 08:52
-
You definitely have to put in key though. Without them jwt.io can't validate the token. – juunas Jul 05 '22 at 06:16
2 Answers
Here is a working manual JWT validation to compare against, from my Azure AD development account. Hopefully this enables you to solve your own problem, and also highlights the steps many API security libraries follow:
JWT ACCESS TOKEN
eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImtpZCI6IjJaUXBKM1VwYmpBWVhZR2FYRUpsOGxWMFRPSSJ9.eyJhdWQiOiJjYjM5OGI0My05NmU4LTQ4ZTYtOGU4ZS1iMTY4ZDU4MTZjMGUiLCJpc3MiOiJodHRwczovL2xvZ2luLm1pY3Jvc29mdG9ubGluZS5jb20vN2YwNzFmYmMtOGJmMi00ZTYxLWJiNDgtZGFiZDhlMmY1YjVhL3YyLjAiLCJpYXQiOjE2NTY4NjQxOTIsIm5iZiI6MTY1Njg2NDE5MiwiZXhwIjoxNjU2ODY4NjEzLCJhaW8iOiJBVFFBeS84VEFBQUFaVE9ydkw3K0tVQXdlOWlVSVdTdEdSdlhibVJqdFpKVUlnWjQyL1NWSE5rZ041d25hRjJQaDV3M0g1bnJzeVpFIiwiYXpwIjoiYzVlYTZkNzgtYzYzNy00ZjdmLWIyMzgtMjI2NGY1ZDRiNDc5IiwiYXpwYWNyIjoiMCIsImVtYWlsIjoiZ3Vlc3R1c2VyQG15Y29tcGFueS5jb20iLCJuYW1lIjoiR3Vlc3RVc2VyIiwib2lkIjoiMTUxYTI1NjQtMmFjMy00ZTY3LThiMzEtYmZhYjdjZjgxZDVlIiwicHJlZmVycmVkX3VzZXJuYW1lIjoiZ3Vlc3R1c2VyQGdhcnlhcmNoZXIzNmdtYWlsLm9ubWljcm9zb2Z0LmNvbSIsInJoIjoiMC5BU0VBdkI4SGZfS0xZVTY3U05xOWppOWJXa09MT2N2b2x1WklqbzZ4YU5XQmJBNGhBUGsuIiwic2NwIjoic2NvcGUyIHRyYW5zYWN0aW9uc19yZWFkIiwic3ViIjoiaUhBWVNJdHN3cHh4aE5RSHA4TFptSlRYcEt3S2tyWEZDY1VKOW5BRHlMNCIsInRpZCI6IjdmMDcxZmJjLThiZjItNGU2MS1iYjQ4LWRhYmQ4ZTJmNWI1YSIsInV0aSI6IkYtNk0zejlQTWtpRVFPZnd1c2ZJQUEiLCJ2ZXIiOiIyLjAifQ.El2_6XP_MxILKvEif2gKR6XS2sRPLFr2oZHBA9VdRS-l_iWGSO3JhqwK26WvAqsYVDL3mKfubUUjh5r0vKuWDwpciWSTLey3ptPAm1ApeQF4C3xBIpvLQDQI3vO7bzs0Xd4du5AOc0c513NSVshr9DqdVJY_sSiwyBVQx0qliWeqiKIwi5B7NnUJji680ZYOvoPTCYBtKwnKQRpaqOh9P1KxghFafkEcVb-_wVGpjwMi-iMKpM1QWDgfsjCJIRueW_s-KE6jS7pEeYJFGt0epft548ek0gdThF_2apAEiLGUsy65Ucu8n6OQZVXFcRMw6dHx5v4zA3CBeSiVACpeqQ
KID VALUE FROM JWT HEADER
2ZQpJ3UpbjAYXYGaXEJl8lV0TOI
JWKS URI
The JSON Web Keyset containing token signing public keys is downloaded from here:
https://login.microsoftonline.com/7f071fbc-8bf2-4e61-bb48-dabd8e2f5b5a/discovery/v2.0/keys
TOKEN SIGNING PUBLIC KEY (JWK FORMAT)
This is the item in the keyset that matches the kid
field from the JWT header. You can paste this JSON into the public key text field in jwt.io and the JWT will pass validation:
{
"kty": "RSA",
"use": "sig",
"kid": "2ZQpJ3UpbjAYXYGaXEJl8lV0TOI",
"x5t": "2ZQpJ3UpbjAYXYGaXEJl8lV0TOI",
"n": "wEMMJtj9yMQd8QS6Vnm538K5GN1Pr_I31_LUl9-OCYu-9_DrDvPGjViQK9kOiCjBfyqoAL-pBecn9-XXaS-C4xZTn1ZRw--GELabuo0u-U6r3TKj42xFDEP-_R5RpOGshoC95lrKiU5teuhn4fBM3XfR2GB0dVMcpzN3h4-0OMvBK__Zr9tkQCU_KzXTbNCjyA7ybtbr83NF9k3KjpTyOyY2S-qvFbY-AoqMhL9Rp8r2HBj_vrsr6RX6GeiSxxjbEzDFA2VIcSKbSHvbNBEeW2KjLXkz6QG2LjKz5XsYLp6kv_-k9lPQBy_V7Ci4ZkhAN-6j1S1Kcq58aLbp0wDNKQ",
"e": "AQAB",
"x5c": [
"MIIDBTCCAe2gAwIBAgIQH4FlYNA+UJlF0G3vy9ZrhTANBgkqhkiG9w0BAQsFADAtMSswKQYDVQQDEyJhY2NvdW50cy5hY2Nlc3Njb250cm9sLndpbmRvd3MubmV0MB4XDTIyMDUyMjIwMDI0OVoXDTI3MDUyMjIwMDI0OVowLTErMCkGA1UEAxMiYWNjb3VudHMuYWNjZXNzY29udHJvbC53aW5kb3dzLm5ldDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMBDDCbY/cjEHfEEulZ5ud/CuRjdT6/yN9fy1JffjgmLvvfw6w7zxo1YkCvZDogowX8qqAC/qQXnJ/fl12kvguMWU59WUcPvhhC2m7qNLvlOq90yo+NsRQxD/v0eUaThrIaAveZayolObXroZ+HwTN130dhgdHVTHKczd4ePtDjLwSv/2a/bZEAlPys102zQo8gO8m7W6/NzRfZNyo6U8jsmNkvqrxW2PgKKjIS/UafK9hwY/767K+kV+hnokscY2xMwxQNlSHEim0h72zQRHltioy15M+kBti4ys+V7GC6epL//pPZT0Acv1ewouGZIQDfuo9UtSnKufGi26dMAzSkCAwEAAaMhMB8wHQYDVR0OBBYEFLFr+sjUQ+IdzGh3eaDkzue2qkTZMA0GCSqGSIb3DQEBCwUAA4IBAQCiVN2A6ErzBinGYafC7vFv5u1QD6nbvY32A8KycJwKWy1sa83CbLFbFi92SGkKyPZqMzVyQcF5aaRZpkPGqjhzM+iEfsR2RIf+/noZBlR/esINfBhk4oBruj7SY+kPjYzV03NeY0cfO4JEf6kXpCqRCgp9VDRM44GD8mUV/ooN+XZVFIWs5Gai8FGZX9H8ZSgkIKbxMbVOhisMqNhhp5U3fT7VPsl94rilJ8gKXP/KBbpldrfmOAdVDgUC+MHw3sSXSt+VnorB4DU4mUQLcMriQmbXdQc8d1HUZYZEkcKaSgbygHLtByOJF44XUsBotsTfZ4i/zVjnYcjgUQmwmAWD"
],
"issuer": "https://login.microsoftonline.com/7f071fbc-8bf2-4e61-bb48-dabd8e2f5b5a/v2.0"
}
TOKEN SIGNING PUBLIC KEY (PEM FORMAT)
You can use a JWK to PEM converter to convert the JWK to PEM format. You can paste this certificate text into the public key text field in jwt.io and the JWT will also pass validation:
-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAwEMMJtj9yMQd8QS6Vnm5
38K5GN1Pr/I31/LUl9+OCYu+9/DrDvPGjViQK9kOiCjBfyqoAL+pBecn9+XXaS+C
4xZTn1ZRw++GELabuo0u+U6r3TKj42xFDEP+/R5RpOGshoC95lrKiU5teuhn4fBM
3XfR2GB0dVMcpzN3h4+0OMvBK//Zr9tkQCU/KzXTbNCjyA7ybtbr83NF9k3KjpTy
OyY2S+qvFbY+AoqMhL9Rp8r2HBj/vrsr6RX6GeiSxxjbEzDFA2VIcSKbSHvbNBEe
W2KjLXkz6QG2LjKz5XsYLp6kv/+k9lPQBy/V7Ci4ZkhAN+6j1S1Kcq58aLbp0wDN
KQIDAQAB
-----END PUBLIC KEY-----

- 22,534
- 2
- 12
- 24
-
Hi thank you a lot for your help. I did use the method you are describing here. It worked with code but I sttrugled with jwt.io. – Idash Jul 15 '22 at 14:43
so I dont know what happened but when I stopped filling the key boxes, jwt.io finally validated the token on its own... so maybe jwt.io detected automatically the token as a token signed by Microsoft Azure and retrieved the public key on its own. Thanks a lot you all four help

- 55
- 8