passlib.utils - Helper Functions

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:

Constants

passlib.utils.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 host_context and ldap_context to determine which hashes are supported by the host.

See also

Identifiers & Platform Support for a table of which OSes are known to support which hashes.

Unicode Helpers

passlib.utils.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.

New in version 1.6.

Changed in version 1.7: This is an alias for stdlib’s hmac.compare_digest() under Python 3.3 and up.

passlib.utils.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 used to refer to identify source parameter in error messages (Defaults to the string "value"). This is mainly useful to make the caller’s error messages make more sense.
Raises:

ValueError – if any characters forbidden by the SASLPrep profile are encountered.

Returns:

normalized unicode string

Note

This function is not available under Jython, as the Jython stdlib is missing the stringprep module (Jython issue 1758320).

New in version 1.6.

Bytes Helpers

passlib.utils.xor_bytes(left, right)

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

passlib.utils.render_bytes(source, *args)

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

This function is motivated by the fact that 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.

passlib.utils.int_to_bytes(value, count)

encode integer as single big-endian byte string

passlib.utils.bytes_to_int(value)

decode byte string as single big-endian integer

Encoding Helpers

passlib.utils.is_same_codec(left, right)

Check if two codec names are aliases for same codec

passlib.utils.is_ascii_codec(codec)

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

passlib.utils.is_ascii_safe(source)

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

passlib.utils.to_bytes(source, encoding='utf-8', param='value', source_encoding=None)

Helper to normalize input to bytes.

Parameters:
  • source – Source bytes/unicode to process.
  • encoding – Target encoding (defaults to "utf-8").
  • param – Optional name of variable/noun to reference when raising errors
  • source_encoding – If this is specified, and the source is bytes, the source will be transcoded from source_encoding to encoding (via unicode).
Raises:

TypeError – if source is not unicode or bytes.

Returns:

  • 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.

passlib.utils.to_unicode(source, encoding='utf-8', param='value')

Helper to normalize input to unicode.

Parameters:
  • source – source bytes/unicode to process.
  • encoding – encoding to use when decoding bytes instances.
  • param – optional name of variable/noun to reference when raising errors.
Raises:

TypeError – if source is not unicode or bytes.

Returns:

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

passlib.utils.to_native_str(source, encoding='utf-8', param='value')

Take in unicode or bytes, return native string.

Python 2: encodes unicode using specified encoding, leaves bytes alone. Python 3: leaves unicode alone, decodes bytes using specified encoding.

Raises:

TypeError – if source is not unicode or bytes.

Parameters:
  • source – source unicode or bytes string.
  • encoding – encoding to use when encoding unicode or decoding bytes. this defaults to "utf-8".
  • param – optional name of variable/noun to reference when raising errors.
Returns:

str instance

Randomness

passlib.utils.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.

passlib.utils.getrandbytes(rng, count)

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

passlib.utils.getrandstr(rng, charset, count)

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

passlib.utils.generate_password(size=10, charset=<default charset>)

generate random password using given length & charset

param size:

size of password.

param 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:

str containing randomly generated password.

Note

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

Deprecated since version 1.7: and will be removed in version 2.0, use passlib.pwd.genword() / passlib.pwd.genphrase() instead.

Interface Tests

passlib.utils.is_crypt_handler(obj)

check if object follows the PasswordHash API

passlib.utils.is_crypt_context(obj)

check if object appears to be a CryptContext instance

passlib.utils.has_rounds_info(handler)

check if handler provides the optional rounds information attributes

passlib.utils.has_salt_info(handler)

check if handler provides the optional salt information attributes