Home > database >  Can't find a way to decrypt a JWT token generated from a ASP.net app in Python
Can't find a way to decrypt a JWT token generated from a ASP.net app in Python

Time:01-02

I have been trying to decrypt a JTW Token that is generated in ASP.net by using the code below

public string GenerateJwtToken(ICollection<Claim> claims)
    {
        var signingKey =
            new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_configuration["Identity:Jwt:SigningKey"]));
        var encryptionKey =
            new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_configuration["Identity:Jwt:EncryptionKey"]));

        var signingCredentials = new SigningCredentials(signingKey, SecurityAlgorithms.HmacSha512);
        var expires = _systemClock.UtcNow.DateTime.AddHours(24);
        var issueDateTime = _systemClock.UtcNow.DateTime;

        var encryptingCredentials = new EncryptingCredentials(
            encryptionKey,
            JwtConstants.DirectKeyUseAlg,
            SecurityAlgorithms.Aes256CbcHmacSha512);

        var securityToken = new JwtSecurityTokenHandler().CreateJwtSecurityToken(
            _configuration["Identity:Jwt:Issuer"],
            _configuration["Identity:Jwt:Audience"],
            new ClaimsIdentity(claims),
            issueDateTime,
            expires,
            issueDateTime,
            signingCredentials,
            encryptingCredentials);

        return new JwtSecurityTokenHandler().WriteToken(securityToken);
    }

I am trying to decrypt it in Python.

I have tried using few libraries and the closest I got is with jwcrypto lib but now I am getting some error regarding jwcrypto.jws.InvalidJWSSignature: Verification failed for all signatures["Failed: [InvalidJWSSignature('Verification failed')]"]

Here is my Python code (Token :

from jwcrypto import jwt, jwk, jwe
import base64

s = "<Identity:Jwt:EncryptionKey>" # The same key that is used in the ASP.net app
base64_bytes = base64.b64encode(s.encode("utf-8"))
base64_string = base64_bytes.decode("utf-8")

# Convert the Base64 string to Base64Url
base64_string = base64_string.rstrip("=")
base64_string = base64_string.replace(" ", "-")
base64_string = base64_string.replace("/", "_")

print(base64_string)

k = {"k": base64_string, "kty": "oct"}
key = jwk.JWK(**k)
token = "eyJhbGciOiJkaXIiLCJlbmMiOiJBMjU2Q0JDLUhTNTEyIiwidHlwIjoiSldUIn0..4C1FW4w2BZ6Nq5jzM1jbdQ.LJqaiSsaIxRgFw9vTs8zNhHH824JJyfU6Jmxi7hta8OyeUO11Df4HuFzC-3PyVrhI0lICtGqmY6BeaaQkquJIz65XgOi9sdR1tBNHkc5bKjTyoXxW65QbdaDhvjpFJXoe66eTPn32tf2M6VDU6w1hJitQgVpq8v11rUf2YqP0g-vkZbxTmD-Cd5BY6hHSuJ_CJ1SDIYzVGKw7mDudM0Opm9EeXEbtVZCL7YagziG_WSryfCaUh9OLulre4SOvZ8T5t5duADEn4MHiYRUZjNbXZIhsWsLfxhINhspekoS4ha8rYQSIHH8208TD4wckQ3zx70XYNHbQiqSr3Atlt-zXPIG1MsfXZJOrg4-KFeKaWxlMfyx3iPiSRisILQm-ATGDnRxHewEuU0gwLyHkwTsyObO7zIuDs82RMgCB5jFs-PK27YHPplv26w9WDQ1F88Lbiumxv9j1zvF6rTQEFte7OnHJD9BpxTDmC9vvUNbdsBLn2tlhAtWKU-oBUOtA-vJIiWz3lt_Mz5Xj1G9WlcHtcUNi-kv_ZFDz45gmG-nhvHDZE3Sp8qnyko8W6tmDusXI6nTwseQ3FrQgUCR69jJ_bEvGjGzqrJ2Pv0qFcyNuHZglB8CvX3kALoMeRyYuV_ULD0wEDd8QET-w_6gKj1-aPfGqcWbJO0JRxphWNJcVLcicoe3fWqyXrmv6iPWZsKcmEYE2T3qco3dVeoYgC-EkPBROfHXzvBdb9ABqfW2dc782fPHXhahZkJJNfXaxNC6Lc8COe-DjQVUtU-z-VL6erhmgzb-G178A074q3kX2b1nDp4zEMs4t704SEdSyo4uKzamKwXtbc_XwKb-Xcda_udoWhW1KiQkJktHhYnZ6g1dcUjQ0G5R9P8hX3T597mNJyHq8lVr6hYhWXRZZLm_1w.VL2-nxFdi3b3-lUy-Oi0sQOPTwgVmdIkLV9TLBYNYUs"
ET = jwt.JWT(key=key, jwt=token, expected_type="JWE")
print(ET.claims)
ST = jwt.JWT(key=key, jwt=ET.claims)
print(ST.claims) 


But I can't seem to make it work, would be great if anyone can enlighten me on how I can decrypt the token.

Thank you

CodePudding user response:

Be aware that the C# library applied first signs the JWT (JWS) and then encrypts the signed JWT (JWE), which is why there are two keys, one for encryption and one for signing, see here.

The current Python code does not take this into account. Instead it uses the same key for decryption and verification, namely the encryption key. However, for verification the signing key must be used.

Example:

The following encrypted JWT:

eyJhbGciOiJkaXIiLCJlbmMiOiJBMjU2Q0JDLUhTNTEyIiwidHlwIjoiSldUIiwiY3R5IjoiSldUIn0..RUhT_5WjzRut6_SLvwkinA.OOx5ZuPyfGHzqA8MrR6AmzYkmv6EbgQsgoEBuWAFx85Ce03jMSjoNxgYSOVpdBmn73rc3d91N2J_GF71DzvMwq1F0Q9xcNML2_gB_39H61VDIMJJXfk7aRZvZUHZCIDzd6LvjAjqW5Q6zeT4YKkLk9thH1hjl9FRqqZb11UxKpRGXFNnZihzVP7_4BbhUoCT03k-YH2reG7Ss3JMktqlRnTqhsVltuBdXCs_jTQ7_fiJqMRc21NootxlhNIkum9aOv-003_whOB3UP7TK8L9iSxrO7sGBkSnh8dayS_iGxsrSEnfpd82HMVYF-1wMSfNsUi5-UH7OJZ9TjnXwolD5vBPB6OCZsSBmLVvHbkP4EA.DUHsU5XZu2RVvQ49EX5Tg4FADJq77eZPX9OhnyUgRrc

was created with the C# code using the encryption key

0123456789012345678901234567890123456789012345678901234567890123

and the signing key

0123456789012345 

as well as sample values for issuer, audience and subject.

It can be decrypted with JWCrypto as follows:

from jwcrypto import jwt, jwk, jwe
import base64

# decryption
rawEncKey = b"0123456789012345678901234567890123456789012345678901234567890123" 
encJWK = {"k": base64.urlsafe_b64encode(rawEncKey).decode(), "kty": "oct"}
encKey = jwk.JWK(**encJWK)
token = "eyJhbGciOiJkaXIiLCJlbmMiOiJBMjU2Q0JDLUhTNTEyIiwidHlwIjoiSldUIiwiY3R5IjoiSldUIn0..RUhT_5WjzRut6_SLvwkinA.OOx5ZuPyfGHzqA8MrR6AmzYkmv6EbgQsgoEBuWAFx85Ce03jMSjoNxgYSOVpdBmn73rc3d91N2J_GF71DzvMwq1F0Q9xcNML2_gB_39H61VDIMJJXfk7aRZvZUHZCIDzd6LvjAjqW5Q6zeT4YKkLk9thH1hjl9FRqqZb11UxKpRGXFNnZihzVP7_4BbhUoCT03k-YH2reG7Ss3JMktqlRnTqhsVltuBdXCs_jTQ7_fiJqMRc21NootxlhNIkum9aOv-003_whOB3UP7TK8L9iSxrO7sGBkSnh8dayS_iGxsrSEnfpd82HMVYF-1wMSfNsUi5-UH7OJZ9TjnXwolD5vBPB6OCZsSBmLVvHbkP4EA.DUHsU5XZu2RVvQ49EX5Tg4FADJq77eZPX9OhnyUgRrc"
ET = jwt.JWT(key=encKey, jwt=token, expected_type="JWE")
print("JWT:", ET.claims)

# verification
rawSigKey = b"0123456789012345" 
sigJWK = {"k": base64.urlsafe_b64encode(rawSigKey).decode(), "kty": "oct"}
sigKey = jwk.JWK(**sigJWK)
ST = jwt.JWT(key=sigKey, jwt=ET.claims)
print("payload:", ST.claims) 

with the output:

JWT: eyJhbGciOiJIUzUxMiIsInR5cCI6IkpXVCJ9.eyJ1c2VyIjoic29tZV91c2VybmFtZSIsIm5iZiI6MTY3MjU5Njg1MywiZXhwIjoxNjcyNjgzMjUzLCJpYXQiOjE2NzI1OTY4NTMsImlzcyI6Imlzc3VlciIsImF1ZCI6ImF1ZGllbmNlIn0.KaweJITus79GvZwX-OF_7Yc1u2X6VNrv8tuCkpvjwa5yEI5MJPnY4u7T87Zxpw__KcD1-_pJYTPeQuycRUrAfg
payload: {"user":"some_username","nbf":1672596853,"exp":1672683253,"iat":1672596853,"iss":"issuer","aud":"audience"}
  • Related