def libcrypt_password(password, crypted_password=None): """ we use crypt type sha512, which is a secure and standard according to: http://security.stackexchange.com/questions/20541/\ insecure-versions-of-crypt-hashes :param password: the plain text password :param crypted_password: optional - the encrypted password if the encrypted password is provided the salt and the hash algo is taken from it, so that same password will result in same output - which is used for password comparison :return: the encrypted password """ if crypted_password: return libcrypt(password, crypted_password) ctype = '6' salt_len = 20 b_salt = os.urandom(3 * ((salt_len + 3) // 4)) # we use base64 charset for salt chars as it is nearly the same # charset, if '+' is changed to '.' and the fillchars '=' are # striped off salt = base64.b64encode(b_salt).strip("=").replace('+', '.') # now define the password format by the salt definition insalt = '$%s$%s$' % (ctype, salt[0:salt_len]) encryptedPW = libcrypt(password, insalt) return encryptedPW
def compare_password(password, crypted_password): """ comparing passwords for password comparison the passwords crypt algorithms are supported, which are indicated by the "$ID$" prefix : ID | Method ───────────────────────────────────────────────────────── 1 | MD5 2a | Blowfish (not in mainline glibc; added in some | Linux distributions) 5 | SHA-256 (since glibc 2.7) 6 | SHA-512 (since glibc 2.7) to upport passowrds on a broad range of platforms the passlib library is used: https://passlib.readthedocs.io/en/stable/index.html algorithm: we iterate over supported list of passlib modules to identify the hashing algorithm (s.o.) and do the comparison with the matching one. :param password: the plain text password :param crypted_password: the encrypted password :return: boolean - for the password comparison result """ if PasslibHashes.identify(crypted_password): return PasslibHashes.verify(password, crypted_password) # compatibilty case: # the rare case for the broken system crypto libs like on macos new_crypted_passw = libcrypt(password, crypted_password) return compare(new_crypted_passw, crypted_password)