Skip to content

passlib.utils - Helper Functions

Internal helpers for implementing password hashes.

Warning

This module is primarily used as an internal support module. Its interface has not been finalized yet, and may be changed somewhat between major releases of Passlib, as the internal code is cleaned up and simplified.

This module primarily contains utility functions used internally by Passlib. However, end-user applications may find some of the functions useful, in particular:

  • consteq()
  • saslprep()
  • generate_password()

Constants

unix_crypt_schemes

List of the names of all the hashes in passlib.hash which are natively supported by crypt() on at least one operating system.

For all hashes in this list, the expression passlib.hash.{alg}.has_backend("os_crypt") will return True if the host OS natively supports the hash. This list is used by passlib.hosts.host_context and passlib.apps.ldap_context to determine which hashes are supported by the host.

Tip

See the MCF identifiers table for which OSes are known to support which hashes.

Unicode Helpers

consteq(left, right)

Check two strings/bytes for equality.

This is functionally equivalent to left == right, but attempts to take constant time relative to the size of the righthand input.

The purpose of this function is to help prevent timing attacks during digest comparisons: the standard == operator aborts after the first mismatched character, causing its runtime to be proportional to the longest prefix shared by the two inputs. If an attacker is able to predict and control one of the two inputs, repeated queries can be leveraged to reveal information about the content of the second argument. To minimize this risk, consteq() is designed to take THETA(len(right)) time, regardless of the contents of the two strings. It is recommended that the attacker-controlled input be passed in as the left-hand value.

Warning

This function is not perfect. Various VM-dependant issues (e.g. the VM's integer object instantiation algorithm, internal unicode representation, etc), may still cause the function's run time to be affected by the inputs, though in a less predictable manner. To minimize such risks, this function should not be passed unicode inputs that might contain non- ASCII characters.

Note

Added in 1.6. Changed in 1.7: This is an alias for stdlib's hmac.compare_digest under Python 3.3 and up.

consteq

consteq(left, right)

saslprep

saslprep(source, param='value')

Normalizes unicode strings using SASLPrep stringprep profile.

The SASLPrep profile is defined in :rfc:4013. It provides a uniform scheme for normalizing unicode usernames and passwords before performing byte-value sensitive operations such as hashing. Among other things, it normalizes diacritic representations, removes non-printing characters, and forbids invalid characters such as \n. Properly internationalized applications should run user passwords through this function before hashing.

Parameters:

  • source –

    unicode string to normalize & validate

  • param –

    Optional noun identifying source parameter in error messages (Defaults to the string "value"). This is mainly useful to make the caller's error messages make more sense contextually.

Returns:

  • –

    normalized unicode string

    .. note::

    This function is not available under Jython,
    as the Jython stdlib is missing the :mod:`!stringprep` module
    (`Jython issue 1758320 <http://bugs.jython.org/issue1758320>`_).
    

    .. versionadded:: 1.6

Raises:

  • ValueError –

    if any characters forbidden by the SASLPrep profile are encountered.

  • TypeError –

    if input is not :class:!unicode

Bytes Helpers

xor_bytes

xor_bytes(left: bytes, right: bytes) -> bytes

Perform bitwise-xor of two byte strings (must be same size)

render_bytes

render_bytes(source, *args)

Peform % formating using bytes in a uniform manner across Python 2/3.

This function is motivated by the fact that :class:bytes instances do not support % or {} formatting under Python 3. This function is an attempt to provide a replacement: it converts everything to unicode (decoding bytes instances as latin-1), performs the required formatting, then encodes the result to latin-1.

Calling render_bytes(source, *args) should function roughly the same as source % args under Python 2.

.. todo:: python >= 3.5 added back limited support for bytes %, can revisit when 3.3/3.4 is dropped.

int_to_bytes

int_to_bytes(value, count)

bytes_to_int

bytes_to_int(value)

Encoding Helpers

is_same_codec

is_same_codec(left: str, right: str) -> bool

Check if two codec names are aliases for same codec

is_ascii_codec

is_ascii_codec(codec: str) -> bool

Test if codec is compatible with 7-bit ascii (e.g. latin-1, utf-8; but not utf-16)

is_ascii_safe

is_ascii_safe(source: AnyStr) -> bool

Check if string (bytes or unicode) contains only 7-bit ascii

to_bytes

to_bytes(
    source: str | bytes,
    encoding: str = "utf-8",
    param: str = "value",
    source_encoding: str | None = None,
) -> bytes

Helper to normalize input to bytes.

Parameters:

  • source (str | bytes) –

    Source bytes/unicode to process.

  • encoding (str, default: 'utf-8' ) –

    Target encoding (defaults to "utf-8").

  • param (str, default: 'value' ) –

    Optional name of variable/noun to reference when raising errors

  • source_encoding (str | None, default: None ) –

    If this is specified, and the source is bytes, the source will be transcoded from source_encoding to encoding (via unicode).

Returns:

  • bytes –
    • unicode strings will be encoded using encoding, and returned.
    • if source_encoding is not specified, byte strings will be returned unchanged.
    • if source_encoding is specified, byte strings will be transcoded to encoding.

Raises:

  • TypeError –

    if source is not str or bytes.

to_unicode

to_unicode(
    source: AnyStr, encoding="utf-8", param="value"
) -> str

Helper to normalize input to unicode.

Parameters:

  • source (AnyStr) –

    source bytes/unicode to process.

  • encoding –

    encoding to use when decoding bytes instances.

  • param –

    optional name of variable/noun to reference when raising errors.

Returns:

  • str –
    • returns unicode strings unchanged.
    • returns bytes strings decoded using encoding

Raises:

  • TypeError –

    if source is not str or bytes.

to_native_str

to_native_str(
    source: AnyStr, encoding="utf-8", param="value"
) -> str

Take in str or bytes, returns str. leaves str alone, decodes bytes using specified encoding.

Parameters:

  • source (AnyStr) –

    source unicode or bytes string

  • encoding –

    encoding to use when encoding unicode or decoding bytes

  • param –

    optional name of variable/noun to reference when raising errors

Randomness

rng

The random number generator used by Passlib to generate salt strings and other things which don't require a cryptographically strong source of randomness.

If os.urandom() support is available, this will be an instance of random.SystemRandom, otherwise it will use the default python PRNG class, seeded from various sources at startup.

rng module-attribute

rng: Random = random.SystemRandom()

getrandbytes

getrandbytes(rng, count)

return byte-string containing count number of randomly generated bytes, using specified rng

getrandstr

getrandstr(rng, charset, count)

return string containing count number of chars/bytes, whose elements are drawn from specified charset, using specified rng

generate_password

generate_password(size=10, charset=_52charset)

generate random password using given length & charset

Parameters:

  • size –

    size of password.

  • charset –

    optional string specified set of characters to draw from.

    the default charset contains all normal alphanumeric characters, except for the characters 1IiLl0OoS5, which were omitted due to their visual similarity.

Returns:

  • –

    :class:!str containing randomly generated password.

    .. note::

    Using the default character set, on a OS with :class:`!SystemRandom` support,
    this function should generate passwords with 5.7 bits of entropy per character.
    

Interface Tests

is_crypt_handler

is_crypt_handler(obj)

check if object follows the :ref:password-hash-api

is_crypt_context

is_crypt_context(obj)

check if object appears to be a :class:~passlib.context.CryptContext instance

has_rounds_info

has_rounds_info(handler)

check if handler provides the optional :ref:rounds information <rounds-attributes> attributes

has_salt_info

has_salt_info(handler)

check if handler provides the optional :ref:salt information <salt-attributes> attributes

Submodules

There are also a few submodules which provide additional utility functions: