123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105 |
- # ---------------------------
- #Fichier : security.py
- #Date : 14.10.2020
- #But :
- #Remarque :
- #------------------------------
- import random, string, base64, hmac, re
- SCRYPT_N = 65536
- SCRYPT_SALT_LEN = 16
- API_ID_LEN = 24
- def implode(pw_hash, salt):
- """
- Implodes the given hash and its arguments into a string
- :param pw_hash: password hash
- :param salt: hash salt
- :returns: hash string with arguments in order (salt,hash)
- """
- return '$' + salt + '$' + pw_hash
- def explode(hashstr):
- """
- Explodes a hash string whose values are separated by '$' into an array
- :param hashstr: hash string to explode
- :returns: elements of the given hash string as an array
- """
- return hashstr.split('$')
- def pw_complexity(password):
- """
- Checks the password complexity before using it
- :param password: password to verify complexity
- :returns: true if the password is complex enoughs, false otherwise
- """
- # Dans le cas d'un mot de passe inférieur à 8 caractères
- if (len(password) < 8):
- return False
- # Dans le cas d'un mot de passe sans chiffre
- if (re.search(r"\d", password) is None):
- return False
- # Dans le cas d'un mot de passe sans majuscule
- if (re.search(r"[A-Z]", password) is None):
- return False
- # Dans le cas d'un mot de passe sans minuscule
- if (re.search(r"[a-z]", password) is None):
- return False
- return True
- def hash_pw(password):
- """
- Hashes the given password using scrypt and a random salt
- :param password: password to hash
- :returns: hashed password with arguments
- """
- salt = gen_rand_string()
- pw_hash = base64.b64encode(
- hmac.new(
- key=salt.encode('utf8'),
- msg=password.encode('utf8'),
- digestmod='SHA256'
- ).digest()
- ).decode('utf8')
- return implode(pw_hash, salt)
- def check_pw(password, pw_hash):
- """
- Checks whether the specified password and parameters match the given hash
- :param password: password to check
- :param pw_hash: hash string to compare with
- :returns: True if the password is correct, else False
- """
- hashvars = explode(pw_hash)
- mac = base64.b64decode(pw_hash)
- return hmac.compare_digest(hashvars[2].encode('utf8'), base64.b64encode(hmac.new(
- key=hashvars[1].encode('utf8'),
- msg=password.encode('utf8'),
- digestmod='SHA256'
- ).digest()))
- def gen_rand_string(prefix=None):
- """
- Generates a random string of 24 characters (alphanumeric case-sensitive)
- :param prefix: prefix to append to the random string
- :returns: random string of 24 alphanumeric characters (case-sensitive)
- """
- return (prefix + '_' if prefix != None else '') + ''.join(
- random.SystemRandom().choice(
- string.ascii_letters + string.digits
- ) for _ in range(API_ID_LEN)
- )
|