CompareHashAndPassword compares the hash and password, returns nil if equal otherwise an error. Context can be used to cancel the hashing if the algorithm supports it.
(ctx context.Context, hash, password string)
| 336 | // password, returns nil if equal otherwise an error. Context can be used to |
| 337 | // cancel the hashing if the algorithm supports it. |
| 338 | func CompareHashAndPassword(ctx context.Context, hash, password string) error { |
| 339 | if strings.HasPrefix(hash, Argon2Prefix) { |
| 340 | return compareHashAndPasswordArgon2(ctx, hash, password) |
| 341 | } else if strings.HasPrefix(hash, FirebaseScryptPrefix) { |
| 342 | return compareHashAndPasswordFirebaseScrypt(ctx, hash, password) |
| 343 | } |
| 344 | |
| 345 | // assume bcrypt |
| 346 | hashCost, err := bcrypt.Cost([]byte(hash)) |
| 347 | if err != nil { |
| 348 | return err |
| 349 | } |
| 350 | |
| 351 | attributes := []attribute.KeyValue{ |
| 352 | attribute.String("alg", "bcrypt"), |
| 353 | attribute.Int("bcrypt_cost", hashCost), |
| 354 | } |
| 355 | |
| 356 | compareHashAndPasswordSubmittedCounter.Add(ctx, 1, metric.WithAttributes(attributes...)) |
| 357 | defer func() { |
| 358 | attributes = append(attributes, attribute.Bool( |
| 359 | "match", |
| 360 | !errors.Is(err, bcrypt.ErrMismatchedHashAndPassword), |
| 361 | )) |
| 362 | |
| 363 | compareHashAndPasswordCompletedCounter.Add(ctx, 1, metric.WithAttributes(attributes...)) |
| 364 | }() |
| 365 | |
| 366 | err = bcrypt.CompareHashAndPassword([]byte(hash), []byte(password)) |
| 367 | return err |
| 368 | } |
| 369 | |
| 370 | // GenerateFromPassword generates a password hash from a |
| 371 | // password, using PasswordHashCost. Context can be used to cancel the hashing |