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