-
Notifications
You must be signed in to change notification settings - Fork 17.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
x/crypto/bcrypt: document handling of zero bytes #36016
Comments
The C bcrypt library (which PHP uses) has a limitation: the password cannot contain any 0 bytes. If there is a 0 byte in the password, everything after it is ignored for the purposes of the calculating the hash. Go intentionally does not emulate this behaviour. There are a couple workarounds. First, you can strip off everything following a 0 byte yourself before calling https://play.golang.org/p/Gv2ZyJoXnn0 result := pbkdf2.Key([]byte(test.password), salt1, 35000, 32, sha512.New)
if i := bytes.IndexByte(result, 0); i >= 0 {
result = result[:i]
}
fmt.Println(bcrypt.CompareHashAndPassword([]byte(test.expectedPassword), result)) However, it's probably a bad idea to discard key material like that. If interoperability with the C library is a concern, a better solution would be to avoid passing binary data to bcrypt in the first place. result := pbkdf2.Key([]byte(test.password), salt1, 35000, 32, sha512.New)
result = []byte(hex.EncodeToString(result))
fmt.Println(bcrypt.CompareHashAndPassword([]byte(test.expectedPassword), result)) |
As @magical said, silently discarding data from the input is dangerous and not a bahavior we want to replicate. For random inputs there is a 1/256 chance the first byte will be a zero, in which case the hash generated by the PHP library will always be the same, which is a security issue. You should probably encode the input. We should mention this behavior in the docs, though. |
Could I try to pick this issue? |
Go for it. |
I am wondering where is the document that I should add to? |
Change https://go.dev/cl/516916 mentions this issue: |
What version of Go are you using (
go version
)?Does this issue reproduce with the latest release?
yes.
What operating system and processor architecture are you using (
go env
)?go env
OutputWhat did you do?
bcrypt.CompareHashAndPassword is error for this case ( "fxIyAIbpWcmAtQ==", "$2y$10$xMl6FD2r7TEHtm0j0hNSeOp5hA3FNWiJjSe/qbgEwZot/sohdZpBi").
the playground link is https://play.golang.org/p/ZdHeD1h6xW-
fxIyAIbpWcmAtQ==, $2y$10$xMl6FD2r7TEHtm0j0hNSeOp5hA3FNWiJjSe/qbgEwZot/sohdZpBi
But in php this case is right.
in php 5.6:
the salt in php at password_hash is right.
What did you expect to see?
bcrypt.CompareHashAndPassword return nil.
What did you see instead?
bcrypt.CompareHashAndPassword return "crypto/bcrypt: hashedPassword is not the hash of the given password"
The text was updated successfully, but these errors were encountered: