New Application Quickstart Guide¶
Need to quickly get password hash support added into your new application, but don’t have time to wade through pages of documentation, comparing and contrasting all the different schemes? Then read on...
Choosing a Hash¶
If you’d like to set up a configuration that’s right for your application, the first thing to do is choose a password hashing scheme. Passlib contains a large number of schemes, but most of them should only be used when a specific format is explicitly required.
See also
If you already know what hash algorithm(s) you want to use, skip to the next section: Creating and Using a CryptContext.
The Options¶
There are currently four good choices [1] for secure hashing:
All four hashes share the following properties:
- No known vulnerabilities.
- Based on documented & widely reviewed algorithms.
- Public-domain or BSD-licensed reference implementations available.
- variable rounds for configuring flexible cpu cost on a per-hash basis.
- At least 96 bits of salt.
- Basic algorithm has seen heavy scrutiny and use for at least 10 years (except for Argon2, born around 2013).
- In use across a number of OSes and/or a wide variety of applications.
While Argon2 is much younger than the others, it has seen heavy scrutiny, and was purpose-designed for password hashing. In the near future, it stands likely to become the recommended standard.
Detailed Comparison of Choices¶
Making a Decision¶
For new applications, this decision comes down to a couple of questions:
Does the hash need to be natively supported by your operating system’s
crypt()
api, in order to allow inter-operation with third-party applications on the host?- If yes, the right choice is either
bcrypt
for BSD variants, orsha512_crypt
for Linux; since these are natively supported. - If no, continue...
- If yes, the right choice is either
Does your hosting provider allow you to install C extensions?
- If no, you probably want to use
pbkdf2_sha256
, as this currently has the fastest pure-python backend. - If they allow C extensions, continue...
- If no, you probably want to use
Do you want to use the latest & greatest, and don’t mind increased memory usage when hashing?
argon2
is a next-generation hashing algorithm, attempting to become the new standard. It’s design has been being slightly tweaked since 2013, but will quite likely become the standard in the next few years. You’ll need to install the argon2_cffi support library.- If you want something secure, but more battle tested, continue...
The top choices left are
bcrypt
andpbkdf2_sha256
.Both have advantages, and their respective rough edges; though currently the balance is in favor of bcrypt (pbkdf2 can be cracked somewhat more efficiently).
Creating and Using a CryptContext¶
Once you’ve chosen what password hash(es) you want to use,
the next step is to define a CryptContext
object
to manage your hashes and related policy configuration.
Insert the following code into your application:
#
# import the CryptContext class, used to handle all hashing...
#
from passlib.context import CryptContext
#
# create a single global instance for your app...
#
pwd_context = CryptContext(
# Replace this list with the hash(es) you wish to support.
# this example sets pbkdf2_sha256 as the default,
# with additional support for reading legacy des_crypt hashes.
schemes=["pbkdf2_sha256", "des_crypt"],
# Automatically mark all but first hasher in list as deprecated.
# (this will be the default in Passlib 2.0)
deprecated="auto",
# Optionally, set the number of rounds that should be used.
# Appropriate values may vary for different schemes,
# and the amount of time you wish it to take.
# Leaving this alone is usually safe, and will use passlib's defaults.
## pbkdf2_sha256__rounds = 29000,
)
To start using your CryptContext, import the context you created wherever it’s needed:
>>> # import context from where you defined it...
>>> from myapp.model.security import pwd_context
>>> # hashing a password...
>>> hash = pwd_context.hash("somepass")
>>> hash
'$pbkdf2-sha256$29000$BSBkLEXIeS9FKMW4F.I85w$SJMzqVU7fw49NDOJZHt2o9vKIfDUVM4cKlAD4MxIgD0'
>>> # verifying a password...
>>> pwd_context.verify("somepass", hash)
True
>>> pwd_context.verify("wrongpass", hash)
False
There’s many more features packed into the context objects, read the walkthrough for more...
See also
- CryptContext Tutorial – full details of using the CryptContext class
passlib.context
– CryptContext API referencepasslib.hash
– list of all hashes supported by Passlib.
Footnotes
[1] | As of June 2016, the most commonly used password hashes are BCrypt and PBKDF2, followed by SHA512-Crypt, with Argon2 rapidly moving up the ranks. You should make sure you are reading a current copy of the Passlib documentation, in case the state of things has changed. |