Search code examples
pythonbcrypt

Python bcrypt: how to check a long encrypted by sha256 password?


I have a long password I want to encode. I use the bcrypt main tutorial:

>>> password = b"an incredibly long password" * 10
>>> hashed = bcrypt.hashpw(
...     base64.b64encode(hashlib.sha256(password).digest()),
...     bcrypt.gensalt()
... )

However, when I check using the tutorial as follows, it does not match:

input_password = "..." # some password
bcrypt.checkpw(input_password.encode("utf8"), hashed)

I think I have to decode it as well. Should base64.b64encode(hashlib.sha256(input_password).digest() work?


Solution

  • To anyone reading this in the future: OP is right. From the BCrypt GitHub:

    The bcrypt algorithm only handles passwords up to 72 characters, any characters beyond that are ignored. To work around this, a common approach is to hash a password with a cryptographic hash (such as sha256) and then base64 encode it to prevent NULL byte problems before hashing the result with bcrypt:

    >>> password = b"an incredibly long password" * 10
    >>> hashed = bcrypt.hashpw(
    ...     base64.b64encode(hashlib.sha256(password).digest()),
    ...     bcrypt.gensalt()
    ... )
    

    To now answer the question:
    Yes, to check the password, you do the same steps witht he password as you did before, so

    >>> new_password = base64.b64encode(hashlib.sha256(raw_password).digest())
    >>> bcrypt.checkpw(new_password, saved_password)
    

    Don't forget to encode the passwords first, so for Python 3 something like

    >>> raw_password = password_string.encode('utf_8')
    

    It's likely a good a idea to encode to the same format.