ticarpi / jwt_tool

:snake: A toolkit for testing, tweaking and cracking JSON Web Tokens
GNU General Public License v3.0
5.47k stars 671 forks source link

Error during signature verification. #41

Closed hugo-syn closed 3 years ago

hugo-syn commented 3 years ago

Hi, I'm using _jwttool to perform attacks on a JWT token using the RS256 algorithms. I have the public key to check for the signature, but the tool is telling me that the signature is invalid. My token is valid, I can use it on my application and I checked with the PyJWT library which also say that the token is valid. So I'm wondering why the _jwttool.py script say that the signature is not valid.

$ cat key.pub
-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAq/Uptco13UyCUkJA9yTB
ZXsQWDA7UeAXr6qzD8TlEgwrV+bygZfa/sENCEf1c+ih78nlcxAYcnOE5tBToxH4
p7RqhosrshZnfQa7vycP4U9z0LEAJLOrfVi/FOEoIyXJXQ4A3wLDOm2kWLGUZTpA
A+RaQKkunwNkUbATL1N9jbG19VEH0/hsBPr5JDs9UlIqTs8h1DjzDfXr6dapdUd6
3ZjBzO+GTheyZoRf93Aqfp54f/AN0VsZ5QhUcFRqr6koZPB7cPDK4HsYAhRuf4xD
pTeILoQ72teCrpLfCZKh0nAView8MbJP3UYZZNmzMOlaE/zTi2W3HWVp4uDEkF8B
cQIDAQAB
-----END PUBLIC KEY-----

$ python3 jwt_tool.py -V -pk key.pub eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICJWLWluY0lORkJRUF9Ucm9MbGZuYUFvdnk0VGgxNUxLQzNBR2IzZFI5cVg0In0.eyJleHAiOjE2MTc4ODM4MzYsImlhdCI6MTYxNzg4MzUzNiwiYXV0aF90aW1lIjoxNjE3ODgzNTM1LCJqdGkiOiI4MTllMWM3ZC1mNTAwLTQ3MmQtODk1ZC01NmVjMWQ4NTEzY2EiLCJpc3MiOiJodHRwczovLzAuMC4wLjA6ODQ0My9hdXRoL3JlYWxtcy90ZXN0IiwiYXVkIjoiYWNjb3VudCIsInN1YiI6IjI3ZTYzNWFjLTEyMDAtNGRiYy05ZmIzLWFkNjE2ZWI2MjZmMCIsInR5cCI6IkJlYXJlciIsImF6cCI6ImFjY291bnQtY29uc29sZSIsIm5vbmNlIjoiYjQwOWM5ZTctZjVhOC00YzFkLTg2NTctOGIyODAyZTdhZWM5Iiwic2Vzc2lvbl9zdGF0ZSI6IjFkMjJkODM2LTVjY2MtNDBjZi1hNzNlLWYxNGYzYjhjYTdhNSIsImFjciI6IjEiLCJyZXNvdXJjZV9hY2Nlc3MiOnsiYWNjb3VudCI6eyJyb2xlcyI6WyJtYW5hZ2UtYWNjb3VudCIsIm1hbmFnZS1hY2NvdW50LWxpbmtzIl19fSwic2NvcGUiOiJvcGVuaWQgZW1haWwgcHJvZmlsZSIsImVtYWlsX3ZlcmlmaWVkIjpmYWxzZSwicHJlZmVycmVkX3VzZXJuYW1lIjoidGVzdCJ9.koCgf_1AIzusXLsiMuKTBKP0-dBdC8SPXEe1Bk5KeAZFQptXeMW8RZWWOEarJy9mp9HCVTv4eQRRx7lTjmVlVvpd2InrdjzcLjesmhOYYz7jBPPfFQm9lsu04WaSw9IBXeYp7f0m45kxjwX8eb36rtLUKQDssFyWWdjE5-_JRrHjA7wxHsHRFwcf4lSCnTnULXsA-7tvSHb7bnN93u2FBP9-J97eInb89pCoM13xKiwD9UBrkVoXiWNCqRPaq20zTyH9tajh8J9ebaIkBklb9xby1_224o6g6ilqQUy_8Hwy6ByEBL6q83EfQxfwpi8tVTyqCsNtlXBAEO1OorXy5Q

        \   \        \         \          \                    \ 
   \__   |   |  \     |\__    __| \__    __|                    |
         |   |   \    |      |          |       \         \     |
         |        \   |      |          |    __  \     __  \    |
  \      |      _     |      |          |   |     |   |     |   |
   |     |     / \    |      |          |   |     |   |     |   |
\        |    /   \   |      |          |\        |\        |   |
 \______/ \__/     \__|   \__|      \__| \______/  \______/ \__|
 Version 2.2.2                \______|             @ticarpi      

Original JWT: 

RSA Signature is INVALID

With the PyJWT library the signature verification suceeds:

>>> token = "eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICJWLWluY0lORkJRUF9Ucm9MbGZuYUFvdnk0VGgxNUxLQzNBR2IzZFI5cVg0In0.eyJleHAiOjE2MTc4ODM4MzYsImlhdCI6MTYxNzg4MzUzNiwiYXV0aF90aW1lIjoxNjE3ODgzNTM1LCJqdGkiOiI4MTllMWM3ZC1mNTAwLTQ3MmQtODk1ZC01NmVjMWQ4NTEzY2EiLCJpc3MiOiJodHRwczovLzAuMC4wLjA6ODQ0My9hdXRoL3JlYWxtcy90ZXN0IiwiYXVkIjoiYWNjb3VudCIsInN1YiI6IjI3ZTYzNWFjLTEyMDAtNGRiYy05ZmIzLWFkNjE2ZWI2MjZmMCIsInR5cCI6IkJlYXJlciIsImF6cCI6ImFjY291bnQtY29uc29sZSIsIm5vbmNlIjoiYjQwOWM5ZTctZjVhOC00YzFkLTg2NTctOGIyODAyZTdhZWM5Iiwic2Vzc2lvbl9zdGF0ZSI6IjFkMjJkODM2LTVjY2MtNDBjZi1hNzNlLWYxNGYzYjhjYTdhNSIsImFjciI6IjEiLCJyZXNvdXJjZV9hY2Nlc3MiOnsiYWNjb3VudCI6eyJyb2xlcyI6WyJtYW5hZ2UtYWNjb3VudCIsIm1hbmFnZS1hY2NvdW50LWxpbmtzIl19fSwic2NvcGUiOiJvcGVuaWQgZW1haWwgcHJvZmlsZSIsImVtYWlsX3ZlcmlmaWVkIjpmYWxzZSwicHJlZmVycmVkX3VzZXJuYW1lIjoidGVzdCJ9.koCgf_1AIzusXLsiMuKTBKP0-dBdC8SPXEe1Bk5KeAZFQptXeMW8RZWWOEarJy9mp9HCVTv4eQRRx7lTjmVlVvpd2InrdjzcLjesmhOYYz7jBPPfFQm9lsu04WaSw9IBXeYp7f0m45kxjwX8eb36rtLUKQDssFyWWdjE5-_JRrHjA7wxHsHRFwcf4lSCnTnULXsA-7tvSHb7bnN93u2FBP9-J97eInb89pCoM13xKiwD9UBrkVoXiWNCqRPaq20zTyH9tajh8J9ebaIkBklb9xby1_224o6g6ilqQUy_8Hwy6ByEBL6q83EfQxfwpi8tVTyqCsNtlXBAEO1OorXy5Q"
>>> pub_key = "-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAq/Uptco13UyCUkJA9yTBZXsQWDA7UeAXr6qzD8TlEgwrV+bygZfa/sENCEf1c+ih78nlcxAYcnOE5tBToxH4p7RqhosrshZnfQa7vycP4U9z0LEAJLOrfVi/FOEoIyXJXQ4A3wLDOm2kWLGUZTpAA+RaQKkunwNkUbATL1N9jbG19VEH0/hsBPr5JDs9UlIqTs8h1DjzDfXr6dapdUd63ZjBzO+GTheyZoRf93Aqfp54f/AN0VsZ5QhUcFRqr6koZPB7cPDK4HsYAhRuf4xDpTeILoQ72teCrpLfCZKh0nAView8MbJP3UYZZNmzMOlaE/zTi2W3HWVp4uDEkF8BcQIDAQAB\n-----END PUBLIC KEY-----"
>>> jwt.decode(token, key=pub_key, algorithms=['RS256'], verify_signature=True, audience="account")
{'exp': 1617883836, 'iat': 1617883536, 'auth_time': 1617883535, 'jti': '819e1c7d-f500-472d-895d-56ec1d8513ca', 'iss': 'https://0.0.0.0:8443/auth/realms/test', 'aud': 'account', 'sub': '27e635ac-1200-4dbc-9fb3-ad616eb626f0', 'typ': 'Bearer', 'azp': 'account-console', 'nonce': 'b409c9e7-f5a8-4c1d-8657-8b2802e7aec9', 'session_state': '1d22d836-5ccc-40cf-a73e-f14f3b8ca7a5', 'acr': '1', 'resource_access': {'account': {'roles': ['manage-account', 'manage-account-links']}}, 'scope': 'openid email profile', 'email_verified': False, 'preferred_username': 'test'}

Thanks !

ticarpi commented 3 years ago

Hmm, tricky one.

The reason this fails is because the original token provided uses an unusual JSON syntax in the header: eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICJWLWluY0lORkJRUF9Ucm9MbGZuYUFvdnk0VGgxNUxLQzNBR2IzZFI5cVg0In0 {"alg":"RS256","typ" : "JWT","kid" : "V-incINFBQP_TroLlfnaAovy4Th15LKC3AGb3dR9qX4"} Specifically having spaces either side of the colons in a couple of places.

As jwt_tool supports modifying tokens the process actually disassembles and reconstructs the tokens (with no spaces between the colons as general JSON conventions). This largely works fine, however in some outliers you make get errors/issues where the original JSON doesn't match the reconstructed JSON.

FWIW the fact that the spacing is inconsistent hints at a bug in the token generation.

hugo-syn commented 3 years ago

Thank you !