Commit ca08234a authored by David Sinquin's avatar David Sinquin

login handler: Use constant-time comparaison for hashes.

An attacker knowing the salt but not the hash could try timming-attacks
to guess a password hash and then try to find it from the hash.
Although not a high risk, there is no good reason not to use a
constant-time comparison, hence this commit.
parent 3244a46d
...@@ -35,6 +35,7 @@ import os ...@@ -35,6 +35,7 @@ import os
from base64 import encodestring, decodestring, b64encode, b64decode from base64 import encodestring, decodestring, b64encode, b64decode
from collections import OrderedDict from collections import OrderedDict
from django.contrib.auth import hashers from django.contrib.auth import hashers
from hmac import compare_digest as constant_time_compare
ALGO_NAME = "{SSHA}" ALGO_NAME = "{SSHA}"
...@@ -63,12 +64,7 @@ def checkPassword(challenge_password, password): ...@@ -63,12 +64,7 @@ def checkPassword(challenge_password, password):
salt = challenge_bytes[DIGEST_LEN:] salt = challenge_bytes[DIGEST_LEN:]
hr = hashlib.sha1(password.encode()) hr = hashlib.sha1(password.encode())
hr.update(salt) hr.update(salt)
valid_password = True return constant_time_compare(digest, hr.digest())
# La comparaison est volontairement en temps constant
# (pour éviter les timing-attacks)
for i, j in zip(digest, hr.digest()):
valid_password &= i == j
return valid_password
def hash_password_salt(hashed_password): def hash_password_salt(hashed_password):
...@@ -118,7 +114,8 @@ class CryptPasswordHasher(hashers.BasePasswordHasher): ...@@ -118,7 +114,8 @@ class CryptPasswordHasher(hashers.BasePasswordHasher):
""" """
assert encoded.startswith(self.algorithm) assert encoded.startswith(self.algorithm)
salt = hash_password_salt(challenge_password) salt = hash_password_salt(challenge_password)
return crypt.crypt(password.encode(), salt) == challenge.encode() return constant_time_compare(crypt.crypt(password.encode(), salt),
challenge.encode())
def safe_summary(self, encoded): def safe_summary(self, encoded):
""" """
...@@ -159,7 +156,9 @@ class MD5PasswordHasher(hashers.BasePasswordHasher): ...@@ -159,7 +156,9 @@ class MD5PasswordHasher(hashers.BasePasswordHasher):
""" """
assert encoded.startswith(self.algorithm) assert encoded.startswith(self.algorithm)
salt = hash_password_salt(encoded) salt = hash_password_salt(encoded)
return b64encode(hashlib.md5(password.encode() + salt).digest() + salt) == encoded.encode() return constant_time_compare(
b64encode(hashlib.md5(password.encode() + salt).digest() + salt),
encoded.encode())
def safe_summary(self, encoded): def safe_summary(self, encoded):
""" """
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment