# `passlib.hash.sha1_crypt` - SHA-1 Crypt

SHA1-Crypt is a hash algorithm introduced by NetBSD in 2004. It’s based on a variation of the PBKDF1 algorithm, and supports a large salt and variable number of rounds.

See also

password hash usage – for examples of how to use this class via the common hash interface.

## Interface

class passlib.hash.sha1_crypt

  This class implements the SHA1-Crypt password hash, and follows the PasswordHash API.

  It supports a variable-length salt, and a variable number of rounds.

  The `using()` method accepts the following optional keywords:

  Parameters:

    - salt (str) – Optional salt string. If not specified, an 8 character one will be autogenerated (this is recommended). If specified, it must be 0-64 characters, drawn from the regexp range `[./0-9A-Za-z]`.

    - salt_size (int) – Optional number of bytes to use when autogenerating new salts. Defaults to 8 bytes, but can be any value between 0 and 64.

    - rounds (int) – Optional number of rounds to use. Defaults to 480000, must be between 1 and 4294967295, inclusive.

    - relaxed (bool) –

      By default, providing an invalid value for one of the other keywords will result in a `ValueError`. If `relaxed=True`, and the error can be corrected, a `PasslibHashWarning` will be issued instead. Correctable errors include `rounds` that are too small or too large, and `salt` strings that are too long.

      Added in version 1.6.

Note

This class will use the first available of two possible backends:

- stdlib `crypt()`, if the host OS supports sha1-crypt (NetBSD).

- a pure python implementation of sha1-crypt built into Passlib.

You can see which backend is in use by calling the `get_backend()` method.

## Format

An example hash (of `password`) is `$sha1$40000$jtNX3nZ2$hBNaIXkt4wBI2o5rsi8KejSjNqIq`. An sha1-crypt hash string has the format `$sha1$rounds$salt$checksum`, where:

- `$sha1$` is the prefix used to identify sha1-crypt hashes, following the Modular Crypt Format

- `rounds` is the decimal number of rounds to use (40000 in the example).

- `salt` is 0-64 characters drawn from `[./0-9A-Za-z]` (`jtNX3nZ2` in the example).

- `checksum` is 28 characters drawn from the same set, encoding a 168-bit checksum. (`hBNaIXkt4wBI2o5rsi8KejSjNqIq/` in the example).

## Algorithm

The checksum is calculated using a modified version of PBKDF1 [3], replacing its use of the SHA1 message digest with HMAC-SHA1, (which does not suffer from the current vulnerabilities that SHA1 itself does, as well as providing some of the advancements made in PBKDF2).

- first, the HMAC-SHA1 digest of `salt$sha1$rounds` is generated, using the password as the HMAC-SHA1 key.

- then, for `rounds-1` iterations, the previous HMAC-SHA1 digest is fed back through HMAC-SHA1, again using the password as the HMAC-SHA1 key.

- the checksum is then rendered into hash-64 format using an ordering that roughly corresponds to big-endian encoding of 24-bit chunks (see `passlib.hash.sha1_crypt._chk_offsets` for exact byte order).

## Deviations

This implementation of sha1-crypt differs from the NetBSD implementation in a few ways:

- Default Rounds:

  The NetBSD implementation randomly varies the actual number of rounds when generating a new configuration string, in order to decrease predictability. This feature is provided by Passlib to all hashes, via the `CryptContext` class, and so it omitted from this implementation.

- Zero-Padded Rounds:

  The specification does not specify how to deal with zero-padding within the rounds portion of the hash. No existing examples or test vectors have zero padding, and allowing it would result in multiple encodings for the same configuration / hash. To prevent this situation, Passlib will throw an error if the rounds in a hash have leading zeros.

- Restricted salt string character set:

  The underlying algorithm can unambiguously handle salt strings which contain any possible byte value besides `\x00` and `$`. However, Passlib strictly limits salts to the `hash64` character set, as nearly all implementations of sha1-crypt generate and expect salts containing those characters.

- Unicode Policy:

  The underlying algorithm takes in a password specified as a series of non-null bytes, and does not specify what encoding should be used; though a `us-ascii` compatible encoding is implied by nearly all known reference hashes.

  In order to provide support for unicode strings, Passlib will encode unicode passwords using `utf-8` before running them through sha1-crypt. If a different encoding is desired by an application, the password should be encoded before handing it to Passlib.

Footnotes

[1]

description of sha1-crypt algorithm - http://mail-index.netbsd.org/tech-userlevel/2004/05/29/0001.html

[2]

NetBSD implementation of SHA1-Crypt - http://fxr.googlebit.com/source/lib/libcrypt/crypt-sha1.c?v=NETBSD-CURRENT

[3]

rfc defining PBKDF1 & PBKDF2 - http://tools.ietf.org/html/rfc2898 -