I have a Java Spring boot API that a user logs in and is issued a JWT token ( i cant change this code). I have a new python API that needs to parse the JWT to verify its been authenticated.
Java Code
import io.jsonwebtoken.Jwts;
private String secretKey = "CFB86D5E4DC4C11C6AFA9E5DF5AD9"
String jwt = Jwts.builder()
.setSubject(userByUsername.getUsername())
.setIssuedAt(now)
.setNotBefore(now)
.setIssuer("my-authenticator")
.setExpiration(new Date(System.currentTimeMillis() + (1000L * tokenMaxAge)))
.signWith(SignatureAlgorithm.HS256, secretKey)
.compact();
Inside my python code i have
import jwt
token = "eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJhZG1pbiIsImlhdCI6MTY3NDUwMzE2NSwibmJmIjoxNjc0NTAzMTY1LCJpc3MiOiJ0ZXN0IiwiZXhwIjoxNjc0NTA2NzY1fQ.wPc98PTVmZKKUEBmuKZG3Z_fXrC7QLLpLE9BXHR3Sw4"
key = 'CFB86D5E4DC4C11C6AFA9E5DF5AD9'
jwt_options = {
'verify_signature': True,
'verify_exp': False,
'verify_nbf': False,
'verify_iat': True,
'verify_aud': False
}
parts = jwt.decode(token, key, algorithms="HS256", options=jwt_options)
print(parts)
If I set verify_signature = False
everything works and i can parse the jwt. But I need to have this set to true. If I go to jwt.io the signature shows up as verified
I've tried playing around with encoding/decoding the string but Im not sure what I'm missing
I have tried decoding and encoding the key but havn't had success. The secret is the same in the java application and python application
ex1. key = b'CFB86D5E4DC4C11C6AFA9E5DF5AD9'
ex2. key = str(base64.urlsafe_b64decode(CFB86D5E4DC4C11C6AFA9E5DF5AD9), 'utf-8')
ex3. key = base64.urlsafe_b64decode(CFB86D5E4DC4C11C6AFA9E5DF5AD9)
ex4. key = base64.b64decode('CFB86D5E4DC4C11C6AFA9E5DF5AD9') # this gives binascii.Error: Invalid base64-encoded string: number of data characters (29) cannot be 1 more than a multiple of 4
Solution:
So I was able to solve my question but im not sure why it worked. The first consisted of setting my secret to a 256 character string ex. 73357638792F423F4428472B4B6250655368566D597133743677397A24432646 The next step was to encode it to UTF-8 and then b64encode it so:
jwt_options = {
'verify_signature': True,
'verify_exp': False,
'verify_nbf': False,
'verify_iat': True,
'verify_aud': False
}
signature_key = config.config.signature_key
signature_key = b64decode(signature_key.encode("utf-8"))
parts = jwt.decode(self.token, signature_key, algorithms=["HS256"], options=jwt_options)