package auth import ( "crypto/rand" "crypto/subtle" "encoding/base64" "fmt" "strings" "golang.org/x/crypto/argon2" ) func HashPassword(password string) (string, error) { salt := make([]byte, 16) if _, err := rand.Read(salt); err != nil { return "", err } hash := argon2.IDKey([]byte(password), salt, 1, 64*1024, 4, 32) return fmt.Sprintf("argon2id$%s$%s", base64.RawStdEncoding.EncodeToString(salt), base64.RawStdEncoding.EncodeToString(hash)), nil } func VerifyPassword(hashValue, password string) bool { parts := strings.Split(hashValue, "$") if len(parts) != 3 || parts[0] != "argon2id" { return false } salt, err := base64.RawStdEncoding.DecodeString(parts[1]) if err != nil { return false } expected, err := base64.RawStdEncoding.DecodeString(parts[2]) if err != nil { return false } actual := argon2.IDKey([]byte(password), salt, 1, 64*1024, 4, 32) return subtle.ConstantTimeCompare(expected, actual) == 1 }