Skip to content

Commit

Permalink
Implemented a pem_to_der method and a dissect_token one
Browse files Browse the repository at this point in the history
Implemented a method to convert pem format items to der ones. Implemented also a dissect_token method, that split a token in two parts; the original message and the signature. This is also in prevision of a new functionality that's going to be introduced with next releases.
  • Loading branch information
DontPanicO committed Mar 4, 2021
1 parent effc91d commit ffa3c67
Showing 1 changed file with 34 additions and 18 deletions.
52 changes: 34 additions & 18 deletions jwt-crack.py
Original file line number Diff line number Diff line change
Expand Up @@ -1090,6 +1090,15 @@ def craft_token(header_, payload_):
encoded_payload = Cracker.encode_token_segment(payload_)
return encoded_header + "." + encoded_payload

@staticmethod
def dissect_token(jwt):
"""
:param jwt: A JWT
:return: The token original message and the signature
"""
return ".".join(jwt.split(".")[:2]), jwt.split(".")[2]

@staticmethod
def modify_time_claims(qt, iterable, instruction="add"):
"""
Expand Down Expand Up @@ -1157,6 +1166,17 @@ def get_ec_curve(alg):
return None # NEED THIS ELSE?
return curve

@staticmethod
def pem_to_der(pem_sig):
"""
:param pem_sig: A PEM format signature
Convert a base64 url encoded signature (PEM FORMAT)
to bytes (DER FORMAT)
:return: The signature in DER format
"""
return base64.urlsafe_b64decode(Cracker.append_equals_if_needed(pem_sig))

@staticmethod
def sign_token_with_hmac(key, partial_token, sign_hash):
"""
Expand Down Expand Up @@ -1220,8 +1240,7 @@ def verify_token_with_hmac(key, token, sign_hash):
Generates a signature using key and checks if it differs from the JWT one
:return: True, if signatures do not differ, else False. None if token_alg is not valid
"""
untrusted_signature = token.split(".")[2]
partial_token = ".".join(token.split(".")[:2])
partial_token, untrusted_signature = Cracker.dissect_token(token)
our_signature = Cracker.sign_token_with_hmac(key, partial_token, sign_hash)
if our_signature == untrusted_signature:
return True
Expand All @@ -1237,11 +1256,10 @@ def verify_token_with_rsa_pkcs1(key, token, sign_hash):
:return: False if signature is invalid, True else.
"""
partial_token = ".".join(token.split(".")[:2])
untrusted_signature_to_decode = Cracker.append_equals_if_needed(token.split(".")[2])
untrusted_signature = base64.urlsafe_b64decode(untrusted_signature_to_decode)
partial_token, untrusted_pem_signature = Cracker.dissect_token(token)
untrusted_der_signature = Cracker.pem_to_der(untrusted_pem_signature)
try:
is_valid_if_none = key.verify(untrusted_signature, partial_token.encode(), algorithm=sign_hash, padding=padding.PKCS1v15())
is_valid_if_none = key.verify(untrusted_der_signature, partial_token.encode(), algorithm=sign_hash, padding=padding.PKCS1v15())
except InvalidSignature:
return False
if is_valid_if_none is None:
Expand All @@ -1256,12 +1274,11 @@ def verify_token_with_rsa_pss(key, token, sign_hash):
:return: False if signature is invalid, True else.
"""
partial_token = ".".join(token.split(".")[:2])
untrusted_signature_to_decode = Cracker.append_equals_if_needed(token.split(".")[2])
untrusted_signature = base64.urlsafe_b64decode(untrusted_signature_to_decode)
partial_token, untrusted_pem_signature = Cracker.dissect_token(token)
untrusted_der_signature = Cracker.pem_to_der(untrusted_pem_signature)
try:
is_valid_if_none = key.verify(
untrusted_signature, partial_token.encode(), algorithm=sign_hash,
untrusted_der_signature, partial_token.encode(), algorithm=sign_hash,
padding=padding.PSS(mgf=padding.MGF1(sign_hash), salt_length=padding.PSS.MAX_LENGTH)
)
except InvalidSignature:
Expand All @@ -1278,11 +1295,10 @@ def verify_token_with_ec(key, token, sign_hash):
:return: False if signature is invalid, True else.
"""
partial_token = ".".join(token.split(".")[:2])
untrusted_signature_to_decode = Cracker.append_equals_if_needed(token.split(".")[2])
untrusted_signature = base64.urlsafe_b64decode(untrusted_signature_to_decode)
partial_token, untrusted_pem_signature = Cracker.dissect_token(token)
untrusted_der_signature = Cracker.pem_to_der(untrusted_pem_signature)
try:
is_valid_if_none = key.verify(untrusted_signature, partial_token.encode(), ec.ECDSA(sign_hash))
is_valid_if_none = key.verify(untrusted_der_signature, partial_token.encode(), ec.ECDSA(sign_hash))
except InvalidSignature:
return False
if is_valid_if_none is None:
Expand Down Expand Up @@ -1423,8 +1439,8 @@ def gen_rsa_public_key_from_jwk(jwk):
e_64 = jwk['e']
except KeyError:
return None
n_bytes = base64.urlsafe_b64decode(Cracker.append_equals_if_needed(n_64))
e_bytes = base64.urlsafe_b64decode(Cracker.append_equals_if_needed(e_64))
n_bytes = Cracker.pem_to_der(n_64)
e_bytes = Cracker.pem_to_der(e_64)
n = int.from_bytes(n_bytes, byteorder="big")
e = int.from_bytes(e_bytes, byteorder="big")
public_numbers = RSAPublicNumbers(e, n)
Expand All @@ -1446,8 +1462,8 @@ def gen_ec_public_key_from_jwk(jwk, alg):
except KeyError:
return None
ec_curve = Cracker.get_ec_curve(alg)
x_bytes = base64.urlsafe_b64decode(Cracker.append_equals_if_needed(x_64))
y_bytes = base64.urlsafe_b64decode(Cracker.append_equals_if_needed(y_64))
x_bytes = Cracker.pem_to_der(x_64)
y_bytes = Cracker.pem_to_der(y_64)
x = int.from_bytes(x_bytes, byteorder="big")
y = int.from_bytes(y_bytes, byteorder="big")
public_numbers = EllipticCurvePublicNumbers(x, y, ec_curve)
Expand Down

0 comments on commit ffa3c67

Please sign in to comment.