Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix python hashing for deprecated passwords #172

Merged
merged 2 commits into from
Dec 4, 2023
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
2 changes: 1 addition & 1 deletion auth/libraries/pip-auth/authlib/auth_handler.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ def hash(self, to_hash: str) -> str:
return self.hashing_handler.hash(to_hash)

def is_equals(self, to_hash: str, to_compare: str) -> bool:
return self.hashing_handler.verify(hash=to_compare, password=to_hash)
return self.hashing_handler.is_equals(to_hash, to_compare)

def create_authorization_token(self, user_id: int, email: str) -> Response:
return self.token_factory.create(user_id, email)
Expand Down
48 changes: 37 additions & 11 deletions auth/libraries/pip-auth/authlib/hashing_handler.py
Original file line number Diff line number Diff line change
@@ -1,20 +1,46 @@
from typing import Optional
import base64
import hashlib

import argon2


SHA512_HASHED_LENGTH = 152
ARGON2_HASH_START = "$argon2"


class HashingHandler:
def hash(self, to_hash: str, hash_reference: Optional[str] = None) -> str:
def hash(self, to_hash: str) -> str:
ph = argon2.PasswordHasher()
return ph.hash(to_hash)

def verify(self, hash: str, password: str) -> bool:
ph = argon2.PasswordHasher()
try:
return ph.verify(hash, password)
except (
argon2.exceptions.VerifyMismatchError,
argon2.exceptions.VerificationError,
argon2.exceptions.InvalidHashError,
):
def is_equals(self, toHash: str, toCompare: str) -> bool:
if not toHash or not toCompare:
jsangmeister marked this conversation as resolved.
Show resolved Hide resolved
return False
if self.is_argon2_hash(toCompare):
ph = argon2.PasswordHasher()
try:
return ph.verify(toCompare, toHash)
except (
argon2.exceptions.VerifyMismatchError,
argon2.exceptions.VerificationError,
argon2.exceptions.InvalidHashError,
):
return False
elif self.is_sha512_hash(toCompare):
return self.sha512(toHash, toCompare[0:64]) == toCompare
else:
return False

def is_sha512_hash(self, hash: str) -> bool:
return (
not hash.startswith(ARGON2_HASH_START) and len(hash) == SHA512_HASHED_LENGTH
)

def is_argon2_hash(self, hash: str) -> bool:
return hash.startswith(ARGON2_HASH_START)

def sha512(self, to_hash: str, salt: str) -> str:
hash = hashlib.new("sha512", to_hash.encode())
hash.update(salt.encode())
hashValue = base64.b64encode(hash.digest()).decode("utf-8")
return salt + hashValue
9 changes: 9 additions & 0 deletions auth/libraries/pip-auth/tests/test_hashing.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
from authlib.hashing_handler import ARGON2_HASH_START

from .base import BaseTestEnvironment


DEPRECATED_PW_HASH = "316af7b2ddc20ead599c38541fbe87e9a9e4e960d4017d6e59de188b41b2758flD5BVZAZ8jLy4nYW9iomHcnkXWkfk3PgBjeiTSxjGG7+fBjMBxsaS1vIiAMxYh+K38l0gDW4wcP+i8tgoc4UBg==" # noqa: E501


class TestHashing(BaseTestEnvironment):
def test_random_salt(self):
to_hash = "Some password to hash"
Expand All @@ -11,4 +16,8 @@ def test_random_salt(self):
def test_hash_and_is_equals(self):
to_hash = "Some pw"
hash = self.auth_handler.hash(to_hash)
self.assertEqual(hash[0:7], ARGON2_HASH_START)
self.assertTrue(self.auth_handler.is_equals(to_hash, hash))

def test_deprecated_pw(self):
self.assertTrue(self.auth_handler.is_equals("admin", DEPRECATED_PW_HASH))
Loading