[crypto] bcrypt: reject passwords longer than 72 bytes

242 views
Skip to first unread message

Gopher Robot (Gerrit)

unread,
Dec 21, 2022, 12:19:34 PM12/21/22
to Roland Shoemaker, goph...@pubsubhelper.golang.org, golang-...@googlegroups.com, Damien Neil, Sam Mortimer, Jason McNeil, Filippo Valsorda, Dan Kortschak, golang-co...@googlegroups.com

Gopher Robot submitted this change.

View Change



1 is the latest approved patch-set.
The change was submitted with unreviewed changes in the following files:

```
The name of the file: bcrypt/bcrypt_test.go
Insertions: 2, Deletions: 2.

@@ -244,7 +244,7 @@

func TestPasswordTooLong(t *testing.T) {
_, err := GenerateFromPassword(make([]byte, 73), 1)
- if err != errPasswordTooLong {
- t.Errorf("unexpected error: got %q, want %q", err, errPasswordTooLong)
+ if err != ErrPasswordTooLong {
+ t.Errorf("unexpected error: got %q, want %q", err, ErrPasswordTooLong)
}
}
```
```
The name of the file: bcrypt/bcrypt.go
Insertions: 4, Deletions: 2.

@@ -82,7 +82,9 @@
minor byte
}

-var errPasswordTooLong = errors.New("crypto/bcrypt: password too long")
+// ErrPasswordTooLong is returned when the password passed to
+// GenerateFromPassword is too long (i.e. > 72 bytes).
+var ErrPasswordTooLong = errors.New("bcrypt: password length exceeds 72 bytes")

// GenerateFromPassword returns the bcrypt hash of the password at the given
// cost. If the cost given is less than MinCost, the cost will be set to
@@ -92,7 +94,7 @@
// is the longest password bcrypt will operate on.
func GenerateFromPassword(password []byte, cost int) ([]byte, error) {
if len(password) > 72 {
- return nil, errPasswordTooLong
+ return nil, ErrPasswordTooLong
}
p, err := newFromPassword(password, cost)
if err != nil {
```

Approvals: Damien Neil: Looks good to me, but someone else must approve Roland Shoemaker: Run TryBots; Automatically submit change Jason McNeil: Looks good to me, but someone else must approve Gopher Robot: TryBots succeeded Filippo Valsorda: Looks good to me, approved
bcrypt: reject passwords longer than 72 bytes

By design, bcrypt only uses the first 72 bytes of a password when
generating a hash. Most implementations, including the reference one,
simply silently ignore any trailing input when provided passwords longer
than 72 bytes. This can cause confusion for users who expect the entire
password to be used to generate the hash.

In GenerateFromPassword, reject passwords longer than 72 bytes.
CompareHashAndPassword will still accept these passwords, since we
cannot break hashes that have already been stored.

Fixes golang/go#36546

Change-Id: I039addd2a2961a7fa9d1e4a3e892a9e3c8bf4c9a
Reviewed-on: https://go-review.googlesource.com/c/crypto/+/450415
Reviewed-by: Damien Neil <dn...@google.com>
Reviewed-by: Jason McNeil <jmc...@x2studios.com>
TryBot-Result: Gopher Robot <go...@golang.org>
Reviewed-by: Filippo Valsorda <fil...@golang.org>
Auto-Submit: Roland Shoemaker <rol...@golang.org>
Run-TryBot: Roland Shoemaker <rol...@golang.org>
---
M bcrypt/bcrypt.go
M bcrypt/bcrypt_test.go
2 files changed, 44 insertions(+), 0 deletions(-)

diff --git a/bcrypt/bcrypt.go b/bcrypt/bcrypt.go
index addf56b..5577c0f 100644
--- a/bcrypt/bcrypt.go
+++ b/bcrypt/bcrypt.go
@@ -82,11 +82,20 @@
minor byte
}

+// ErrPasswordTooLong is returned when the password passed to
+// GenerateFromPassword is too long (i.e. > 72 bytes).
+var ErrPasswordTooLong = errors.New("bcrypt: password length exceeds 72 bytes")
+
// GenerateFromPassword returns the bcrypt hash of the password at the given
// cost. If the cost given is less than MinCost, the cost will be set to
// DefaultCost, instead. Use CompareHashAndPassword, as defined in this package,
// to compare the returned hashed password with its cleartext version.
+// GenerateFromPassword does not accept passwords longer than 72 bytes, which
+// is the longest password bcrypt will operate on.
func GenerateFromPassword(password []byte, cost int) ([]byte, error) {
+ if len(password) > 72 {
+ return nil, ErrPasswordTooLong
+ }
p, err := newFromPassword(password, cost)
if err != nil {
return nil, err
diff --git a/bcrypt/bcrypt_test.go b/bcrypt/bcrypt_test.go
index b7162d8..8b589e3 100644
--- a/bcrypt/bcrypt_test.go
+++ b/bcrypt/bcrypt_test.go
@@ -241,3 +241,10 @@
t.Errorf("got=%q want=%q", got, want)
}
}
+
+func TestPasswordTooLong(t *testing.T) {
+ _, err := GenerateFromPassword(make([]byte, 73), 1)
+ if err != ErrPasswordTooLong {
+ t.Errorf("unexpected error: got %q, want %q", err, ErrPasswordTooLong)
+ }
+}

To view, visit change 450415. To unsubscribe, or for help writing mail filters, visit settings.

Gerrit-Project: crypto
Gerrit-Branch: master
Gerrit-Change-Id: I039addd2a2961a7fa9d1e4a3e892a9e3c8bf4c9a
Gerrit-Change-Number: 450415
Gerrit-PatchSet: 5
Gerrit-Owner: Roland Shoemaker <rol...@golang.org>
Gerrit-Reviewer: Damien Neil <dn...@google.com>
Gerrit-Reviewer: Filippo Valsorda <fil...@golang.org>
Gerrit-Reviewer: Gopher Robot <go...@golang.org>
Gerrit-Reviewer: Jason McNeil <jmc...@x2studios.com>
Gerrit-Reviewer: Roland Shoemaker <rol...@golang.org>
Gerrit-CC: Dan Kortschak <d...@kortschak.io>
Gerrit-CC: Sam Mortimer <sam.mo...@gmail.com>
Gerrit-MessageType: merged
Reply all
Reply to author
Forward
0 new messages