Keats / rust-bcrypt

Easily hash and verify passwords using Bcrypt
MIT License
340 stars 49 forks source link

allow null bytes in inputs #66

Closed slingamn closed 2 years ago

slingamn commented 2 years ago

I'm the co-maintainer of Ergo, which preprocesses passwords with SHA3-512 and then hashes them with bcrypt. I got a report from a user that they were trying to produce a compatible implementation in Python, but couldn't because raw SHA3-512 output can contain null bytes, which weren't valid as inputs to pyca/bcrypt.

Here's my understanding of the problem:

  1. There is in fact an algorithmic quirk of bcrypt where if two passwords consist entirely of null bytes, they will hash to the same value even if they are of different lengths
  2. In general, however, there is no problem with null bytes as inputs to bcrypt, except in the case of bcrypt APIs that take a C-style char * as input, in which case the null byte will be taken as the end of the password. If one is "pre-hashing" inputs to bcrypt with an ordinary (fast) cryptographic hash function, there is no cryptographic reason to require a subsequent base64 encode step.

This change allows null bytes, adding some new test cases covering their handling. In support of the change:

  1. https://crypto.stackexchange.com/questions/33335/why-does-0x00-make-bcrypt-weaker
  2. The Go implementation, which allows null bytes: https://cs.opensource.google/go/x/crypto/+/86341886:bcrypt/bcrypt.go
  3. 17 cites pyca/bcrypt's decision to reject null bytes as a justification for rejecting them here, but the maintainers of pyca/bcrypt have reconsidered this (as per discussion in https://github.com/pyca/bcrypt/pull/294 and https://github.com/pyca/bcrypt/pull/125)

Thanks very much for your time.

Keats commented 2 years ago

Thanks!