0

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?

Minh-Long Luu
  • 2,393
  • 1
  • 17
  • 39
  • 1
    You are actually using the SHA256 hash as the password. Just supply the password itself to the `hashpw()` function. – Klaus D. Nov 30 '20 at 03:05
  • ^ +1 to Klaus' comment. Ideally, you should use `bcrypt` directly rather than hashing with `SHA256` before using `bcrypt`. (E.g., `hashed = bcrypt.hashpw('secret'.encode('utf-8'), bcrypt.gensalt())`) – Spencer D Nov 30 '20 at 03:08
  • 1
    I saw that bycrypt only supported up to 72 characters, so I tried this way. – Minh-Long Luu Nov 30 '20 at 03:17

1 Answers1

1

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.

Randelung
  • 356
  • 4
  • 10