Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion jose/jwk.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
from jose.constants import ALGORITHMS
from jose.exceptions import JWKError
from jose.utils import base64url_decode
from jose.utils import constant_time_string_compare

# PyCryptodome's RSA module doesn't have PyCrypto's _RSAobj class
# Instead it has a class named RsaKey, which serves the same purpose.
Expand Down Expand Up @@ -159,7 +160,7 @@ def sign(self, msg):
return hmac.new(self.prepared_key, msg, self.hash_alg).digest()

def verify(self, msg, sig):
return sig == self.sign(msg)
return constant_time_string_compare(sig, self.sign(msg))


class RSAKey(Key):
Expand Down
25 changes: 25 additions & 0 deletions jose/utils.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@

import base64
import hmac


def calculate_at_hash(access_token, hash_alg):
Expand Down Expand Up @@ -58,3 +59,27 @@ def timedelta_total_seconds(delta):
delta (timedelta): A timedelta to convert to seconds.
"""
return delta.days * 24 * 60 * 60 + delta.seconds


def constant_time_string_compare(a, b):
"""Helper for comparing string in constant time, independent
of the python version being used.

Args:
a (str): A string to compare
b (str): A string to compare
"""

try:
return hmac.compare_digest(a, b)
except AttributeError:

if len(a) != len(b):
return False

result = 0

for x, y in zip(a, b):
result |= ord(x) ^ ord(y)

return result == 0