Codevault initial commit
This commit is contained in:
37
internal/auth/password.go
Normal file
37
internal/auth/password.go
Normal file
@@ -0,0 +1,37 @@
|
||||
package auth
|
||||
|
||||
import (
|
||||
"crypto/sha256"
|
||||
"encoding/base64"
|
||||
|
||||
"golang.org/x/crypto/bcrypt"
|
||||
)
|
||||
|
||||
// saltedInput mixes the login into the password material before bcrypt hashing, using
|
||||
// the login as a per-user salt: a leaked hash can't be replayed against a different
|
||||
// login, and pre-hashing keeps the input short regardless of login/password length
|
||||
// (bcrypt only considers the first 72 bytes of its input).
|
||||
func saltedInput(login, password string) []byte {
|
||||
sum := sha256.Sum256([]byte(login + "\x00" + password))
|
||||
return []byte(base64.StdEncoding.EncodeToString(sum[:]))
|
||||
}
|
||||
|
||||
// dummyHash is compared against on unknown logins so that a failed lookup takes
|
||||
// roughly the same time as a real password comparison, avoiding user enumeration.
|
||||
var dummyHash, _ = bcrypt.GenerateFromPassword(saltedInput("dummy-login", "dummy-password"), bcrypt.DefaultCost)
|
||||
|
||||
func Hash(login, password string) (string, error) {
|
||||
hash, err := bcrypt.GenerateFromPassword(saltedInput(login, password), bcrypt.DefaultCost)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return string(hash), nil
|
||||
}
|
||||
|
||||
func Compare(login, hash, password string) bool {
|
||||
return bcrypt.CompareHashAndPassword([]byte(hash), saltedInput(login, password)) == nil
|
||||
}
|
||||
|
||||
func CompareDummy() {
|
||||
_ = bcrypt.CompareHashAndPassword(dummyHash, saltedInput("dummy-login", "dummy-password"))
|
||||
}
|
||||
Reference in New Issue
Block a user