12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667 |
- // Copyright 2023 The Gitea Authors. All rights reserved.
- // SPDX-License-Identifier: MIT
-
- package hash
-
- import (
- "encoding/hex"
- "strings"
-
- "code.gitea.io/gitea/modules/log"
-
- "golang.org/x/crypto/scrypt"
- )
-
- func init() {
- MustRegister("scrypt", NewScryptHasher)
- }
-
- // ScryptHasher implements PasswordHasher
- // and uses the scrypt key derivation function.
- type ScryptHasher struct {
- n, r, p, keyLen int
- }
-
- // HashWithSaltBytes a provided password and salt
- func (hasher *ScryptHasher) HashWithSaltBytes(password string, salt []byte) string {
- if hasher == nil {
- return ""
- }
- hashedPassword, _ := scrypt.Key([]byte(password), salt, hasher.n, hasher.r, hasher.p, hasher.keyLen)
- return hex.EncodeToString(hashedPassword)
- }
-
- // NewScryptHasher is a factory method to create an ScryptHasher
- // The provided config should be either empty or of the form:
- // "<n>$<r>$<p>$<keyLen>", where <x> is the string representation
- // of an integer
- func NewScryptHasher(config string) *ScryptHasher {
- // This matches the original configuration for `scrypt` prior to storing hash parameters
- // in the database.
- // THESE VALUES MUST NOT BE CHANGED OR BACKWARDS COMPATIBILITY WILL BREAK
- hasher := &ScryptHasher{
- n: 1 << 16,
- r: 16,
- p: 2, // 2 passes through memory - this default config will use 128MiB in total.
- keyLen: 50,
- }
-
- if config == "" {
- return hasher
- }
-
- vals := strings.SplitN(config, "$", 4)
- if len(vals) != 4 {
- log.Error("invalid scrypt hash spec %s", config)
- return nil
- }
- var err error
- hasher.n, err = parseIntParam(vals[0], "n", "scrypt", config, nil)
- hasher.r, err = parseIntParam(vals[1], "r", "scrypt", config, err)
- hasher.p, err = parseIntParam(vals[2], "p", "scrypt", config, err)
- hasher.keyLen, err = parseIntParam(vals[3], "keyLen", "scrypt", config, err)
- if err != nil {
- return nil
- }
- return hasher
- }
|