SHA-256 Crypt and SHA-512 Crypt were developed in 2008 by Ulrich Drepper [1], designed as the successor to md5_crypt. They include fixes and advancements such as variable rounds, and use of NIST-approved cryptographic primitives. The design involves repeated composition of the underlying digest algorithm, using various arbitrary permutations of inputs. SHA-512 / SHA-256 Crypt are currently the default password hash for many systems (notably Linux), and have no known weaknesses. SHA-256 Crypt is one of the three hashes Passlib recommends for new applications. This class can be used directly as follows:
>>> from passlib.hash import sha256_crypt
>>> # generate new salt, encrypt password
>>> hash = sha256_crypt.encrypt("password")
>>> hash
'$5$rounds=80000$wnsT7Yr92oJoP28r$cKhJImk5mfuSKV9b3mumNzlbstFUplKtQXXMo4G6Ep5'
>>> # same, but with explict number of rounds
>>> sha256_crypt.encrypt("password", rounds=12345)
'$5$rounds=12345$q3hvJE5mn5jKRsW.$BbbYTFiaImz9rTy03GGi.Jf9YY5bmxN0LU3p3uI1iUB'
>>> # verify password
>>> sha256_crypt.verify("password", hash)
True
>>> sha256_crypt.verify("letmein", hash)
False
See also
This class implements the SHA256-Crypt password hash, and follows the Password Hash Interface.
It supports a variable-length salt, and a variable number of rounds.
The encrypt() and genconfig() methods accept the following optional keywords:
| Parameters: |
|
|---|
Note
This class will use the first available of two possible backends:
You can see which backend is in use by calling the get_backend() method.
An example sha256-crypt hash (of the string password) is:
$5$rounds=80000$wnsT7Yr92oJoP28r$cKhJImk5mfuSKV9b3mumNzlbstFUplKtQXXMo4G6Ep5
An sha256-crypt hash string has the format $5$rounds=rounds$salt$checksum, where:
There is also an alternate format $5$salt$checksum, which can be used when the rounds parameter is equal to 5000 (see the implicit_rounds parameter above).
The algorithm used by SHA256-Crypt is laid out in detail in the specification document linked to below [1].
This implementation of sha256-crypt differs from the specification, and other implementations, in a few ways:
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 parameter in a hash has leading zeros.
Restricted salt string character set:
The underlying algorithm can unambigously 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 sha256-crypt generate and expect salts containing those characters, but may have unexpected behaviors for other character values.
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 implementations of sha256-crypt as well as all known reference hashes.
In order to provide support for unicode strings, Passlib will encode unicode passwords using utf-8 before running them through sha256-crypt. If a different encoding is desired by an application, the password should be encoded before handing it to Passlib.
Footnotes
| [1] | (1, 2) Ulrich Drepper’s SHA-256/512-Crypt specification, reference implementation, and test vectors - sha-crypt specification |