Another security question

Steve D'Aprano steve+python at
Fri Dec 23 05:46:53 EST 2016

On Fri, 23 Dec 2016 09:19 pm, Frank Millman wrote:

> Having read the previous thread and various links, I want to review the
> way I handle passwords in my accounting application.
> At present I just store a SHA-1 hash of the password for each user. Here
> are my thoughts on improving this.

SHA-1 hashes are (I believe) vulnerable to pre-computed rainbow tables. This
is where the salt comes in: the salt is not a secret itself, but if
prevents attackers pre-computing rainbow tables.

The question is, is SHA-1 (plus salting) strong enough? I'm not sure.

> 1. Generate a 'salt' for each password. There seem to be two ways in the
> standard library to do this -
>     import os
>     salt = os.urandom(16)
>     import secrets
>     salt = secrets.token_bytes(16)
>     My guess is that it will not make much difference which I use.

secrets is officially the preferred mechanism. os.urandom is the low-level
operating system routine, secrets.* is the high-level interface.

At the moment it is true that there's very little difference in practice,
but that's an implementation detail which could change.

> 2. Store the salt in the database along with the user-id and hashed
> password for each user.
> 3. Generate the password from the string supplied by the user as follows -
>     from hashlib import blake2b
>     password = blake2b('my_password'.encode('utf-8'), salt=salt).digest()
> The hashlib docs have the following warning -
> "Salted hashing (or just hashing) with BLAKE2 or any other general-purpose
> cryptographic hash function, such as SHA-256, is not suitable for hashing
> passwords. See BLAKE2 FAQ for more information."

Why are using Blake2 when the docs explicitly say not to use them in this
way? Have you read the FAQ to see what it says?

“Cheer up,” they said, “things could be worse.” So I cheered up, and sure
enough, things got worse.

More information about the Python-list mailing list