glic3rinu / passlib

Automatically exported from code.google.com/p/passlib
Other
15 stars 3 forks source link

Use SHA512 to avoid bcrypt Truncation #43

Closed GoogleCodeExporter closed 9 years ago

GoogleCodeExporter commented 9 years ago
Bcrypt effectively truncates the password if it goes over a certain threshold 
(varies based on salt size). With the default configuration of passlib that 
seems to be 72 characters. I propose adding a new hash backend that first 
hashes the password using SHA512. This will not negatively affect the strength 
of the password hash because bcrypt(sha512(plaintext)) is not insecure as long 
as sha512 isn't broken. More information: 
http://security.stackexchange.com/questions/6623/pre-hash-password-before-applyi
ng-bcrypt-to-avoid-restricting-password-length .

You can see an example of what I mean:

    >>> import random, string, hashlib
    >>> from passlib.hash import bcrypt
    >>> password = "".join(random.choice(string.ascii_uppercase + string.digits) for x in range(100))
    >>> bcrypt.verify(password, bcrypt.encrypt(password))
    True
    >>> bcrypt.verify(password[:72], bcrypt.encrypt(password))
    True
    >>> bcrypt.verify(password[:71], bcrypt.encrypt(password))
    False
    >>> bcrypt.verify(hashlib.sha512(password).hexdigest(), bcrypt.encrypt(hashlib.sha512(password).hexdigest()))
    True
    >>> bcrypt.verify(hashlib.sha512(password[:72]).hexdigest(), bcrypt.encrypt(hashlib.sha512(password).hexdigest()))
    False
    >>> bcrypt.verify(hashlib.sha512(password[:71]).hexdigest(), bcrypt.encrypt(hashlib.sha512(password).hexdigest()))
    False

Original issue reported on code.google.com by donald.s...@gmail.com on 14 Feb 2013 at 5:41

GoogleCodeExporter commented 9 years ago
That's definitely one of the (few) problems with bcrypt... I should note it in 
the documentation. I'd already had to add a "max password size" flag in 
passlib's unittests to account for it :(

I'd been holding off creating any password algorithms (based on "don't roll 
your own", as well as xkcd's warning about standards - http://xkcd.com/927/). 
That said, a couple of other pending issues were going to make me break that 
rule anyways, and this seems like a nicely straightforward construction, and 
one definitely improves bcrypt's security profile. 

I'll try to add something along these lines into the next passlib release. 
Thanks for posting the issue (and the link)!

Original comment by elic@astllc.org on 18 Feb 2013 at 5:49

GoogleCodeExporter commented 9 years ago
I was planning to wait until 1.7, but that may be a little ways away, and I 
already had this code completed.

Passlib 1.6.2 has been released, and now supports a bcrypt_sha256 hash 
(http://pythonhosted.org/passlib/lib/passlib.hash.bcrypt_sha256.html) which 
should accept unlimited password sizes.

Original comment by elic@astllc.org on 27 Dec 2013 at 12:41