This release rolls up assorted bug & compatibility fixes since 1.7.0.
cisco_pix: Fixed a number of issues which under certain conditions caused prior releases to generate hashes that were unverifiable on Cisco systems.
PasswordHash.hash()will now warn if passed any settings keywords. This usage was deprecated in 1.7.0, but warning wasn’t properly enabled. See Customizing the Configuration for the preferred way to pass settings.
- setup.py: Don’t append timestamp when run from an sdist. This should fix some downstream build issues.
passlib.tests.test_totp: Test suite now traps additional errors that
datetime.utcfromtimestamp()may throw under python 3, which should fix some test failures on architectures with rarer ILP sizes. It also works around Python 3.6 bug 29100.
passlib.tests.utils: General truncation policy details were hammered out, and additional hasher tests were added to enforce them.
- documentation: Various updates & corrections.
Welcome to Passlib 1.7!
This release includes a number of new features, cleans up some long-standing design issues, and contains a number of internal improvements; all part of the roadmap towards a leaner and simpler Passlib 2.0.
- Support for
- TOTP Two-Factor Authentications helpers in the
- The misnamed
PasswordHash.encrypt()method has been renamed to
PasswordHash.hash()(and the old alias deprecated). This is part of a much larger project to clean up passlib’s password hashing API, see the PasswordHash Tutorial for a walkthrough.
- Large speedup of the internal PBKDF2 routines.
- Updated documentation
- Passlib now requires Python 2.6, 2.7, or >= 3.3. Support for Python versions 2.5 and 3.0 through 3.2 have been dropped. Support for PyPy 1.x has also been dropped.
passlib.ext.djangoextension now requires Django 1.8 or better. Django 1.7 and earlier are no longer supported.
- passlib.hash.argon2 – Support for the Argon2 password hash (issue 69).
- passlib.hash.scrypt – New password hash format which uses the SCrypt KDF (issue 8).
- passlib.hash.cisco_asa – Support for Cisco ASA 7.0 and newer hashes (issue 51). Note: this should be considered experimental, and needs verification of it’s test vectors.
passlib.totpmodule provides full support for TOTP tokens on both client and server side. This module contains both low-level primitives, and high-level helpers for persisting and tracking client state.
passlib.pwdmodule added to aid in password generation. Features support for alphanumeric passwords, or generation of phrases using the EFF’s password generation wordlist.
CryptContextobject now has helper methods for dealing with hashes representing disabled accounts (issue 45).
- All hashers which truncate passwords (e.g.
des_crypt) can now be configured to raise a
PasswordTruncateErrorwhen a overly-large password is provided. This configurable via (for example)
bcrypt.using(truncate_error=True).hash(secret), or globally as an option to CryptContext (issue 59).
Other changes of note in Passlib 1.7:
Added support for Django’s Argon2 wrapper (
passlib.apache.HtpasswdFilehas been updated to support all of Apache 2.4’s hash schemes, as well as all host OS crypt formats; allowing for much more secure hashes in htpasswd files.
You can now specify if the default hash should be compatible with apache 2.2 or 2.4, and host-specific or portable. See the
default_schemeskeyword for details.
Large parts of the documentation have been rewritten, to separate tutorial & api reference content, and provide more detail on various features.
Official documentation is now at https://passlib.readthedocs.io
The majority of CryptContext’s internal rounds handling & migration code has been moved to the password hashes themselves, taking advantage of the new
This allows much more flexibility when configuring a hasher directly, as well making it easier for CryptContext to support hash-specific parameters.
PasswordHashunittests now check all hash handlers for basic thread-safety (motivated by the pybcrypt 0.2 concurrency bug).
consteq()is now wraps stdlib’s
hmac.compare_digest()when available (python 2.7.11, python 3.3 and up).
bcrypt: Passlib will now detect and work around a fatal concurrency bug in py-bcrypt 0.2 and earlier (a
PasslibSecurityWarningwill also be issued). Nevertheless, users are strongly encouraged to upgrade to py-bcrypt 0.3 or another bcrypt library if you are using the bcrypt hash.
CryptContextinstances now pass contextual keywords (such as “user”) to the hashes that support them, but ignore them for hashes that don’t (issue 63).
passlib.apachehtpasswd helpers now preserve blank lines and comments, rather than throwing a parse error (issue 73).
passlib.ext.djangoand unittests: compatibility fixes for Django 1.9 / 1.10, and some internal refactoring (issue 68).
django_disabledhash now appends a 40-char alphanumeric string, to match Django’s behavior.
As part of a long-range plan to restructure and simplify both the API and the internals of Passlib, a number of methods have been deprecated & replaced. The eventually goal is a large cleanup and overhaul as part of Passlib 2.0. There will be at least one more 1.x version before Passlib 2.0, to provide a final transitional release (see the Passlib Roadmap).
Password Hash API Deprecations¶
As part of this cleanup, the
PasswordHashAPI (used by all hashes in passlib), has had a number of changes:
PasswordHash Tutorial, which walks through using the new hasher interface.
PasswordHash.encrypt()method has been renamed to
PasswordHash.hash(), to clarify that it’s performing one-way hashing rather than reversiable encryption. A compatibility alias will remain in place until Passlib 2.0. This should fix the longstanding issue 21.
[major] Passing explicit configuration options to the
PasswordHash.encrypt()method (now called
PasswordHash.hash()) is deprecated. To provide settings such as
salt_size, callers should use the new
PasswordHash.using()method, which generates a new hasher with a customized configuration. For example, instead of:>>> sha256_crypt.encrypt("secret", rounds=12345)
... applications should now use:>>> sha256_crypt.using(rounds=12345).hash("secret")
Support for the old syntax will be removed in Passlib 2.0.
This doesn’t apply to contextual options such as
userkeyword, which should still be passed into the
[minor] The little-used
PasswordHash.genconfig()methods have been deprecated. Compatibility aliases will remain in place until Passlib 2.0, at which point they will be removed entirely.
Crypt Context API Deprecations¶
Applications which use passlib’s
CryptContextshould not be greatly affected by this release; only one major deprecation was made:
- [major] To match the
PasswordHashAPI changes above, the
CryptContext.encrypt()method was renamed to
CryptContext.hash(). A compatibility alias will remain until Passlib 2.0.
A fewer internal options and infrequently used features have been deprecated:
CryptContext.hash(): Passing settings keywords to
saltis deprecated. Code should now get ahold of the default hasher, and invoke it explicitly:>>> # for example, calls that did this: >>> context.hash(secret, rounds=1234) >>> # should use this instead: >>> context.handler().using(rounds=1234).hash(secret)
vary_roundsoption has been deprecated, and will be removed in Passlib 2.0. It provided very little security benefit, and was judged not worth the additional code complexity it requires.
[minor] The special wildcard
allscheme name has been deprecated, and will be removed in Passlib 2.0. The only legitimate use was to support
vary_rounds, which itself will be removed in 2.0.
A few other assorted deprecations have been made:
passlib.utils.generate_secret()function has been deprecated in favor of the new
passlib.pwdmodule, and the old function will be removed in Passlib 2.0.
Most of passlib’s internal cryptography helpers have been moved from
passlib.crypto, and the APIs refactored. This allowed unification of various hash management routines, some speed ups to the HMAC and PBKDF2 primitives, and opens up the architecture to support more optional backend libraries.
Compatibility wrappers will be kept in place at the old location until Passlib 2.0.
Some deprecations and internal changes have been made to the
passlib.utils.handlersmodule, which provides the common framework Passlib uses to implement hashers.
More backwards-incompatible relocations are planned for the internal
passlib.utilsmodule in the Passlib 1.8 / 1.9 releases.
Changes in existing behavior:
Scheduled removal of features:
passlib.hash: The little-used method
genconfig()will now always return a valid hash, rather than a truncated configuration string or
passlib.hash: The little-used method
genhash()no longer accepts
Noneas a config argument.
passlib.utils.pbkdf2.pbkdf2()no longer supports custom PRF callables. this was an unused feature, and prevented some useful optimizations.