pbkdf2: fix password comparison

the key len for the derived function must be equal to the len of the
expected key
This commit is contained in:
Nicola Murino
2020-03-28 16:09:06 +01:00
parent 0a9c4914aa
commit b52d078986
2 changed files with 10 additions and 13 deletions

View File

@@ -954,15 +954,11 @@ func comparePbkdf2PasswordAndHash(password, hashedPassword string) (bool, error)
return false, fmt.Errorf("pbkdf2: hash is not in the correct format") return false, fmt.Errorf("pbkdf2: hash is not in the correct format")
} }
var hashFunc func() hash.Hash var hashFunc func() hash.Hash
var hashSize int
if strings.HasPrefix(hashedPassword, pbkdf2SHA256Prefix) { if strings.HasPrefix(hashedPassword, pbkdf2SHA256Prefix) {
hashSize = sha256.Size
hashFunc = sha256.New hashFunc = sha256.New
} else if strings.HasPrefix(hashedPassword, pbkdf2SHA512Prefix) { } else if strings.HasPrefix(hashedPassword, pbkdf2SHA512Prefix) {
hashSize = sha512.Size
hashFunc = sha512.New hashFunc = sha512.New
} else if strings.HasPrefix(hashedPassword, pbkdf2SHA1Prefix) { } else if strings.HasPrefix(hashedPassword, pbkdf2SHA1Prefix) {
hashSize = sha1.Size
hashFunc = sha1.New hashFunc = sha1.New
} else { } else {
return false, fmt.Errorf("pbkdf2: invalid or unsupported hash format %v", vals[1]) return false, fmt.Errorf("pbkdf2: invalid or unsupported hash format %v", vals[1])
@@ -972,11 +968,12 @@ func comparePbkdf2PasswordAndHash(password, hashedPassword string) (bool, error)
return false, err return false, err
} }
salt := vals[3] salt := vals[3]
expected := vals[4] expected, err := base64.StdEncoding.DecodeString(vals[4])
df := pbkdf2.Key([]byte(password), []byte(salt), iterations, hashSize, hashFunc) if err != nil {
buf := make([]byte, base64.StdEncoding.EncodedLen(len(df))) return false, err
base64.StdEncoding.Encode(buf, df) }
return subtle.ConstantTimeCompare(buf, []byte(expected)) == 1, nil df := pbkdf2.Key([]byte(password), []byte(salt), iterations, len(expected), hashFunc)
return subtle.ConstantTimeCompare(df, expected) == 1, nil
} }
// HideUserSensitiveData hides user sensitive data // HideUserSensitiveData hides user sensitive data

View File

@@ -2514,12 +2514,12 @@ func TestPasswordsHashPbkdf2Sha256(t *testing.T) {
user.Password = pbkdf2ClearPwd user.Password = pbkdf2ClearPwd
client, err := getSftpClient(user, usePubKey) client, err := getSftpClient(user, usePubKey)
if err != nil { if err != nil {
t.Errorf("unable to login with pkkdf2 sha1 password: %v", err) t.Errorf("unable to login with pkkdf2 sha256 password: %v", err)
} else { } else {
defer client.Close() defer client.Close()
_, err = client.Getwd() _, err = client.Getwd()
if err != nil { if err != nil {
t.Errorf("unable to get working dir with pkkdf2 sha1 password: %v", err) t.Errorf("unable to get working dir with pkkdf2 sha256 password: %v", err)
} }
} }
user.Password = pbkdf2Pwd user.Password = pbkdf2Pwd
@@ -2547,12 +2547,12 @@ func TestPasswordsHashPbkdf2Sha512(t *testing.T) {
user.Password = pbkdf2ClearPwd user.Password = pbkdf2ClearPwd
client, err := getSftpClient(user, usePubKey) client, err := getSftpClient(user, usePubKey)
if err != nil { if err != nil {
t.Errorf("unable to login with pkkdf2 sha1 password: %v", err) t.Errorf("unable to login with pkkdf2 sha512 password: %v", err)
} else { } else {
defer client.Close() defer client.Close()
_, err = client.Getwd() _, err = client.Getwd()
if err != nil { if err != nil {
t.Errorf("unable to get working dir with pkkdf2 sha1 password: %v", err) t.Errorf("unable to get working dir with pkkdf2 sha512 password: %v", err)
} }
} }
user.Password = pbkdf2Pwd user.Password = pbkdf2Pwd