gitea源码

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081
  1. // Copyright 2023 The Gitea Authors. All rights reserved.
  2. // SPDX-License-Identifier: MIT
  3. package hash
  4. import (
  5. "encoding/hex"
  6. "strings"
  7. "code.gitea.io/gitea/modules/log"
  8. "golang.org/x/crypto/argon2"
  9. )
  10. func init() {
  11. MustRegister("argon2", NewArgon2Hasher)
  12. }
  13. // Argon2Hasher implements PasswordHasher
  14. // and uses the Argon2 key derivation function, hybrant variant
  15. type Argon2Hasher struct {
  16. time uint32
  17. memory uint32
  18. threads uint8
  19. keyLen uint32
  20. }
  21. // HashWithSaltBytes a provided password and salt
  22. func (hasher *Argon2Hasher) HashWithSaltBytes(password string, salt []byte) string {
  23. if hasher == nil {
  24. return ""
  25. }
  26. return hex.EncodeToString(argon2.IDKey([]byte(password), salt, hasher.time, hasher.memory, hasher.threads, hasher.keyLen))
  27. }
  28. // NewArgon2Hasher is a factory method to create an Argon2Hasher
  29. // The provided config should be either empty or of the form:
  30. // "<time>$<memory>$<threads>$<keyLen>", where <x> is the string representation
  31. // of an integer
  32. func NewArgon2Hasher(config string) *Argon2Hasher {
  33. // This default configuration uses the following parameters:
  34. // time=2, memory=64*1024, threads=8, keyLen=50.
  35. // It will make two passes through the memory, using 64MiB in total.
  36. // This matches the original configuration for `argon2` prior to storing hash parameters
  37. // in the database.
  38. // THESE VALUES MUST NOT BE CHANGED OR BACKWARDS COMPATIBILITY WILL BREAK
  39. hasher := &Argon2Hasher{
  40. time: 2,
  41. memory: 1 << 16,
  42. threads: 8,
  43. keyLen: 50,
  44. }
  45. if config == "" {
  46. return hasher
  47. }
  48. vals := strings.SplitN(config, "$", 4)
  49. if len(vals) != 4 {
  50. log.Error("invalid argon2 hash spec %s", config)
  51. return nil
  52. }
  53. parsed, err := parseUIntParam(vals[0], "time", "argon2", config, nil)
  54. hasher.time = uint32(parsed)
  55. parsed, err = parseUIntParam(vals[1], "memory", "argon2", config, err)
  56. hasher.memory = uint32(parsed)
  57. parsed, err = parseUIntParam(vals[2], "threads", "argon2", config, err)
  58. hasher.threads = uint8(parsed)
  59. parsed, err = parseUIntParam(vals[3], "keyLen", "argon2", config, err)
  60. hasher.keyLen = uint32(parsed)
  61. if err != nil {
  62. return nil
  63. }
  64. return hasher
  65. }