Coverage for rfpy/auth/password.py: 100%

20 statements  

« prev     ^ index     » next       coverage.py v7.8.0, created at 2025-04-24 10:52 +0000

1import os 

2import binascii 

3 

4from pbkdf2 import PBKDF2 # type: ignore 

5 

6 

7SALT_BYTE_SIZE = 24 

8HASH_BYTE_SIZE = 24 

9PBKDF2_ITERATIONS = 1000 

10 

11 

12def gensalt(): 

13 return binascii.hexlify(os.urandom(SALT_BYTE_SIZE)) 

14 

15 

16def create_hash(password, salt=None): 

17 """ 

18 creates a hash from a password 

19 @param password: password to be hashed 

20 @param salt: the salt to use to hash the password 

21 @return: the hashed password 

22 """ 

23 if not salt: 

24 salt = gensalt() 

25 return PBKDF2(password, salt, PBKDF2_ITERATIONS).hexread(24) 

26 

27 

28def create_signature(password): 

29 salt = gensalt() 

30 hashed_password = create_hash(password, salt=salt) 

31 return f"1000:{salt.hex()}:{hashed_password}" 

32 

33 

34def validate_hash(password, hash_signature): 

35 """ 

36 validates a password using a hash. 

37 @param hash_signature: the hash stored in the database./ 

38 will be in the format iterations:salt:hash 

39 @param password: the plain text password to be validated 

40 @return: true if password is correct, false if not 

41 """ 

42 _iterations, salt, hashed_password = hash_signature.split(":") 

43 salty_bytes = bytes.fromhex(salt) 

44 return create_hash(password, salty_bytes) == hashed_password