diff --git a/internal/auth/password.go b/internal/auth/password.go index 7761ed3..a4d95a9 100644 --- a/internal/auth/password.go +++ b/internal/auth/password.go @@ -5,6 +5,7 @@ import ( "crypto/subtle" "encoding/base64" "fmt" + "strings" "golang.org/x/crypto/argon2" ) @@ -43,22 +44,30 @@ func HashPassword(password string) (string, error) { // VerifyPassword compares a password against an encoded Argon2id hash. func VerifyPassword(password, encodedHash string) (bool, error) { - var version int - var memory, time uint32 - var threads uint8 - var salt, hash []byte - - _, err := fmt.Sscanf(encodedHash, "$argon2id$v=%d$m=%d,t=%d,p=%d$%s$%s", &version, &memory, &time, &threads, &salt, &hash) - if err != nil { - return false, fmt.Errorf("parse hash: %w", err) + parts := strings.Split(encodedHash, "$") + if len(parts) != 6 { + return false, fmt.Errorf("invalid hash format") } - decodedSalt, err := base64.RawStdEncoding.DecodeString(string(salt)) + var version int + _, err := fmt.Sscanf(parts[2], "v=%d", &version) + if err != nil { + return false, fmt.Errorf("parse version: %w", err) + } + + var memory, time uint32 + var threads uint8 + _, err = fmt.Sscanf(parts[3], "m=%d,t=%d,p=%d", &memory, &time, &threads) + if err != nil { + return false, fmt.Errorf("parse params: %w", err) + } + + decodedSalt, err := base64.RawStdEncoding.DecodeString(parts[4]) if err != nil { return false, fmt.Errorf("decode salt: %w", err) } - decodedHash, err := base64.RawStdEncoding.DecodeString(string(hash)) + decodedHash, err := base64.RawStdEncoding.DecodeString(parts[5]) if err != nil { return false, fmt.Errorf("decode hash: %w", err) }