Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Unique Salt per User using Flask-Security

After reading here a bit about salting passwords, it seems that it's best to use a unique salt for each user. I'm working on implementing Flask-Security atm, and from the documentation it appears you can only set a global salt: ie SECURITY_PASSWORD_SALT = 'thesalt'

Question: How would one go about making a unique salt for each password?

Thanks!

edit: from the docs on Flask-Security, I found this, which seems to again suggest that this module only uses a single salt for all passwords out of the box.

flask_security.utils.get_hmac(password)
    Returns a Base64 encoded HMAC+SHA512 of the password signed with the salt 
    specified by SECURITY_PASSWORD_SALT.
like image 610
Chockomonkey Avatar asked Sep 19 '14 20:09

Chockomonkey


People also ask

Should each user have a different salt?

A unique salt should also be generated every time users change their password. Store salt and password separately. Storing the salt separately from the password makes it harder for attackers to reverse-engineer the password. Make the salt at least the same length as the output hash.

Why must each salt be unique for each password?

The best method to ensure privacy protection is to use a unique salt each time the same user generates or changes their password. The length of the salt is as important as its quality or uniqueness. Very short salts are easier to attack and breach, thereby compromising your password.

What's the minimum size a salt should be in order to keep passwords secure?

Every salt should ideally have a long salt value of at least the same length as the output of the hash. If the output of the hash function used is 256 bits or 32 bytes, the length of the salt value should at least be 32 bytes.

How secure are salted passwords?

Password salting adds a string of 32 or more characters to the password and then hashes it. It's among the most secure techniques to secure passwords that are stored for future authentication without exposing them to a breach.


2 Answers

Yes, Flask-Security does use per-user salts by design if using bcrypt (and other schemes such as des_crypt, pbkdf2_sha256, pbkdf2_sha512, sha256_crypt, sha512_crypt).

The config for 'SECURITY_PASSWORD_SALT' is only used for HMAC encryption. If you are using bcrypt as the hashing algorithm Flask-Security uses passlib for hashing and it generates a random salt during hashing. This confustion is noted in issue 268: https://github.com/mattupstate/flask-security/issues/268

It can be verified in the code, walking from encrypt to passlib:

flask_security/utils.py (lines 143-151, 39, and 269)

def encrypt_password(password):
   ...
   return _pwd_context.encrypt(signed)

_pwd_context = LocalProxy(lambda: _security.pwd_context)

flask_security/core.py (269, 244-251, and 18)

pwd_context=_get_pwd_context(app)

def _get_pwd_context(app):
    ...
    return CryptContext(schemes=schemes, default=pw_hash, deprecated=deprecated)

from passlib.context import CryptContext

and finally from: https://pythonhosted.org/passlib/password_hash_api.html#passlib.ifc.PasswordHash.encrypt

note that each call to encrypt() generates a new salt,

like image 97
trevor Avatar answered Sep 21 '22 19:09

trevor


Turns out that if you use bcrypt, it takes care of the salting and stores it with the hash. So I'll go that route!

Thanks to this topic which lead me to this discovery:

Do I need to store the salt with bcrypt?

like image 29
Chockomonkey Avatar answered Sep 25 '22 19:09

Chockomonkey