December 10: Python Cryptographic Service Modules
Shhh! 🤫 As part of the Python Standard Library traversal, after yesterday's
look at file format modules, today is going to be all about secrets.
Well, all about
hashlib, to be precise.
- There's an awful lot of hash algorithms in
secretsmodule exists and is suitable for (reasonably) strong randomness, eg for generating long secret URLs.
hashlib module grants access to a ton of hash algorithms – not all of which are strong or safe. Please hash data
responsibly and make sure you're up to date on safe choices etc etc. There is one constructor for each algorithm, named
after the lower-cased algorithm. All of these return hash objects, which you feed (byte!) data with
update() and get
hexdigest(). You can pass
usedforsecurity=False to every constructor to permit the use of
insecure and blocked algorithms in restricted settings.
Supported hash algorithms (on most platforms) are MD5, SHA-1, SHA-224, SHA-256, SHA-384, SHA-512 (plus the SHA3-* variants
where appropriate), BLAKE2b, BLAKE2s, SHAKE-128 and SHAKE-256.
algorithms_available will return a set of all currently
Apart from regular hashing functions, you can (and should!) be using key derivation functions for secure password
hashing, which can be configured with a salt and a number of iterations and some other parameters. Use
hmac implements the HMAC RFC, which serves to verify both the data integrity and the authenticity of a given message.
It relies on a secret cryptographic key, which you have to manage separately. As with all cryptography, make sure you
know what you're doing, and that you wouldn't be better off using libraries to handle this for you. Use of the module is
straightforward, but please remember to use
compare_digest instead of
== to protect against timing attacks.
If you want secure random numbers, eg for password hashing or secret storage, use
secrets and not
choice() to pick an element out of a secret,
randbelow to pick a number between 0 and the argument, and
to get an integer with n random bits. Use
token_urlsafe to generate secure tokens, eg
for hard-to-guess URLs or password resets. You can specify the length in bytes, or rely on Python to pick a safe (and
increasing, over the years) default value.