/usr/local/lib/python3.9/site-packages/django/utils
""" Django's standard crypto functions and utilities. """ import hashlib import hmac import secrets from django.conf import settings from django.utils.encoding import force_bytes from django.utils.inspect import func_supports_parameter class InvalidAlgorithm(ValueError): """Algorithm is not supported by hashlib.""" pass def salted_hmac(key_salt, value, secret=None, *, algorithm="sha1"): """ Return the HMAC of 'value', using a key generated from key_salt and a secret (which defaults to settings.SECRET_KEY). Default algorithm is SHA1, but any algorithm name supported by hashlib can be passed. A different key_salt should be passed in for every application of HMAC. """ if secret is None: secret = settings.SECRET_KEY key_salt = force_bytes(key_salt) secret = force_bytes(secret) try: hasher = getattr(hashlib, algorithm) except AttributeError as e: raise InvalidAlgorithm( "%r is not an algorithm accepted by the hashlib module." % algorithm ) from e # We need to generate a derived key from our base key. We can do this by # passing the key_salt and our base key through a pseudo-random function. key = hasher(key_salt + secret).digest() # If len(key_salt + secret) > block size of the hash algorithm, the above # line is redundant and could be replaced by key = key_salt + secret, since # the hmac module does the same thing for keys longer than the block size. # However, we need to ensure that we *always* do this. return hmac.new(key, msg=force_bytes(value), digestmod=hasher) RANDOM_STRING_CHARS = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789" def get_random_string(length, allowed_chars=RANDOM_STRING_CHARS): """ Return a securely generated random string. The bit length of the returned value can be calculated with the formula: log_2(len(allowed_chars)^length) For example, with default `allowed_chars` (26+26+10), this gives: * length: 12, bit length =~ 71 bits * length: 22, bit length =~ 131 bits """ return "".join(secrets.choice(allowed_chars) for i in range(length)) def constant_time_compare(val1, val2): """Return True if the two strings are equal, False otherwise.""" return secrets.compare_digest(force_bytes(val1), force_bytes(val2)) def pbkdf2(password, salt, iterations, dklen=0, digest=None): """Return the hash of password using pbkdf2.""" if digest is None: digest = hashlib.sha256 dklen = dklen or None password = force_bytes(password) salt = force_bytes(salt) return hashlib.pbkdf2_hmac(digest().name, password, salt, iterations, dklen) # TODO: Remove when dropping support for PY38. inspect.signature() is used to # detect whether the usedforsecurity argument is available as this fix may also # have been applied by downstream package maintainers to other versions in # their repositories. if func_supports_parameter(hashlib.md5, "usedforsecurity"): md5 = hashlib.md5 new_hash = hashlib.new else: def md5(data=b"", *, usedforsecurity=True): return hashlib.md5(data) def new_hash(hash_algorithm, *, usedforsecurity=True): return hashlib.new(hash_algorithm)
.
Edit
..
Edit
__init__.py
Edit
__pycache__
Edit
_os.py
Edit
archive.py
Edit
asyncio.py
Edit
autoreload.py
Edit
baseconv.py
Edit
cache.py
Edit
connection.py
Edit
crypto.py
Edit
datastructures.py
Edit
dateformat.py
Edit
dateparse.py
Edit
dates.py
Edit
datetime_safe.py
Edit
deconstruct.py
Edit
decorators.py
Edit
deprecation.py
Edit
duration.py
Edit
encoding.py
Edit
feedgenerator.py
Edit
formats.py
Edit
functional.py
Edit
hashable.py
Edit
html.py
Edit
http.py
Edit
inspect.py
Edit
ipv6.py
Edit
itercompat.py
Edit
jslex.py
Edit
log.py
Edit
lorem_ipsum.py
Edit
module_loading.py
Edit
numberformat.py
Edit
regex_helper.py
Edit
safestring.py
Edit
termcolors.py
Edit
text.py
Edit
timesince.py
Edit
timezone.py
Edit
topological_sort.py
Edit
translation
Edit
tree.py
Edit
version.py
Edit
xmlutils.py
Edit