| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788 |
- import hashlib
- import os
- from .secret_properties import secret_properties
- class secret_generator(metaclass = secret_properties):
- def __init__(self, password: str):
- self.__password = password
- self.__secret = None
- @property
- def password(self) -> str:
- return self.__password
- def validate(self, secret: str) -> bool:
- if not self.__check_secret(secret):
- return False
- hashed, salt = self.__split_secret(secret)
- target_hashed, second_salt = self.__generate_hashed(salt)
- return hashed == target_hashed
- def __check_secret(self, secret: str) -> bool:
- properties = self.__class__
-
- hash_length = properties.hash_hex_length
- salt_length = properties.salt_hex_length
- separator = properties.salt_separator
- if secret.find(separator) != hash_length:
- return False
- if len(secret) != hash_length + salt_length + len(separator):
- return False
- return True
- def __split_secret(self, secret: str) -> [bytes, bytes]:
- properties = self.__class__
- separator = properties.salt_separator
- splited = secret.split(separator)
- hashed = bytes.fromhex(splited[0])
- salt = bytes.fromhex(splited[-1])
- return hashed, salt
- def __generate_hashed(self, salt: bytes | None = None) -> str:
- properties = self.__class__
-
- rounds = properties.hash_rounds
- algorithm = properties.hash_algorithm
- password = self.password.encode("UTF-8")
-
- if salt is None:
- random_size = properties.salt_length
- salt = os.urandom(random_size)
- hashed = hashlib.pbkdf2_hmac(
- algorithm,
- password,
- salt,
- rounds
- )
- return hashed, salt
- @property
- def secret(self) -> str:
- if self.__secret is not None:
- return self.__secret
- hashed, salt = self.__generate_hashed()
- self.__secret = self.__create_secret(hashed, salt)
- return self.secret
- def __create_secret(self, hashed: bytes, salt: bytes) -> str:
- properties = self.__class__
- separator = properties.salt_separator
- result = hashed.hex() + separator + salt.hex()
- if not self.__check_secret(result):
- raise Exception("Can not create secret. Check secret settings!")
- return result
|