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"}