Use SHA512 to avoid bcrypt Truncation

Issue #43 resolved
Anonymous created an issue

(Imported from Google Code)

donald.stufft wrote:

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-applying-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

Comments (2)

  1. Eli Collins repo owner
    • assigned issue to True
    • marked as minor
    • changed status to open
    • changed type to enhancement
    • changed Milestone to 1.7

    (Imported from Google Code)

    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)!

  2. Log in to comment