def hash(cls, secret, **kwds): if kwds: uh.warn_hash_settings_deprecation(cls, kwds) return cls.using(**kwds).hash(secret) uh.validate_secret(secret) marker = cls.default_marker return to_native_str(marker, param='marker')
def from_string(cls, hash): hash = to_native_str(hash, 'ascii', 'hash') if not hash.startswith('$scram$'): raise uh.exc.InvalidHashError(cls) parts = hash[7:].split('$') if len(parts) != 3: raise uh.exc.MalformedHashError(cls) rounds_str, salt_str, chk_str = parts rounds = int(rounds_str) if rounds_str != str(rounds): raise uh.exc.MalformedHashError(cls) try: salt = ab64_decode(salt_str.encode('ascii')) except TypeError: raise uh.exc.MalformedHashError(cls) if not chk_str: raise uh.exc.MalformedHashError(cls) else: if '=' in chk_str: algs = None chkmap = {} for pair in chk_str.split(','): alg, digest = pair.split('=') try: chkmap[alg] = ab64_decode(digest.encode('ascii')) except TypeError: raise uh.exc.MalformedHashError(cls) else: algs = chk_str chkmap = None return cls(rounds=rounds, salt=salt, checksum=chkmap, algs=algs)
def verify(cls, secret, hash, encoding=None): if not encoding: encoding = cls.default_encoding hash = to_native_str(hash, encoding, 'hash') if not cls.identify(hash): raise uh.exc.InvalidHashError(cls) return str_consteq(cls.hash(secret, encoding), hash)
def disable(cls, hash=None): out = cls.hash('') if hash is not None: hash = to_native_str(hash, param='hash') if cls.identify(hash): hash = cls.enable(hash) if hash: out += hash return out
def _norm_hash(cls, hash): hash = to_native_str(hash, param='hash') if len(hash) != 32: raise uh.exc.MalformedHashError(cls, 'wrong size') for char in hash: if char not in uh.LC_HEX_CHARS: raise uh.exc.MalformedHashError(cls, 'invalid chars in hash') return hash
def enable(cls, hash): hash = to_native_str(hash, param='hash') for prefix in cls._disable_prefixes: if hash.startswith(prefix): orig = hash[len(prefix):] if orig: return orig raise ValueError('cannot restore original hash') raise uh.exc.InvalidHashError(cls)
def genhash(cls, secret, config, marker=None): if not cls.identify(config): raise uh.exc.InvalidHashError(cls) else: if config: uh.validate_secret(secret) return to_native_str(config, param='config') if marker is not None: cls = cls.using(marker=marker) return cls.hash(secret) return
def check_bcryptor(secret, hash): secret = to_native_str(secret, self.FuzzHashGenerator.password_encoding) if hash.startswith((IDENT_2B, IDENT_2Y)): hash = IDENT_2A + hash[4:] else: if hash.startswith(IDENT_2): hash = IDENT_2A + hash[3:] if secret: secret = repeat_string(secret, 72) return Engine(False).hash_key(secret, hash) == hash
def test_to_native_str(self): from otp.ai.passlib.utils import to_native_str self.assertEqual(to_native_str(u('abc'), 'ascii'), 'abc') self.assertEqual(to_native_str('abc', 'ascii'), 'abc') if PY3: self.assertEqual(to_native_str(u('\xe0'), 'ascii'), '\xe0') self.assertRaises(UnicodeDecodeError, to_native_str, '\xc3\xa0', 'ascii') else: self.assertRaises(UnicodeEncodeError, to_native_str, u('\xe0'), 'ascii') self.assertEqual(to_native_str('\xc3\xa0', 'ascii'), '\xc3\xa0') self.assertEqual(to_native_str(u('\xe0'), 'latin-1'), '\xe0') self.assertEqual(to_native_str('\xe0', 'latin-1'), '\xe0') self.assertEqual(to_native_str(u('\xe0'), 'utf-8'), '\xe0' if PY3 else '\xc3\xa0') self.assertEqual(to_native_str('\xc3\xa0', 'utf-8'), '\xe0' if PY3 else '\xc3\xa0') self.assertRaises(TypeError, to_native_str, None, 'ascii') return
def check_pybcrypt(secret, hash): secret = to_native_str(secret, self.FuzzHashGenerator.password_encoding) if len(secret) > 200: secret = secret[:200] if hash.startswith((IDENT_2B, IDENT_2Y)): hash = IDENT_2A + hash[4:] try: if lock: with lock: return bcrypt_mod.hashpw(secret, hash) == hash else: return bcrypt_mod.hashpw(secret, hash) == hash except ValueError: raise ValueError('py-bcrypt rejected hash: %r' % (hash, ))
def _get_hash_aliases(name): orig = name if not isinstance(name, str): name = to_native_str(name, 'utf-8', 'hash name') name = re.sub('[_ /]', '-', name.strip().lower()) if name.startswith('scram-'): name = name[6:] if name.endswith('-plus'): name = name[:-5] def check_table(name): for row in _known_hash_names: if name in row: return row result = check_table(name) if result: return result m = re.match('(?i)^(?P<name>[a-z]+)-?(?P<rev>\\d)?-?(?P<size>\\d{3,4})?$', name) if m: iana_name, rev, size = m.group('name', 'rev', 'size') if rev: iana_name += rev hashlib_name = iana_name if size: iana_name += '-' + size if rev: hashlib_name += '_' hashlib_name += size result = check_table(iana_name) if result: return result log.info('normalizing unrecognized hash name %r => %r / %r', orig, hashlib_name, iana_name) else: iana_name = name hashlib_name = name.replace('-', '_') log.warning( 'normalizing unrecognized hash name and format %r => %r / %r', orig, hashlib_name, iana_name) return (hashlib_name, iana_name)
def hash(cls, secret, encoding=None): uh.validate_secret(secret) if not encoding: encoding = cls.default_encoding return to_native_str(secret, encoding, 'secret')