code.gitea.io/gitea@v1.19.3/modules/auth/password/hash/pbkdf2.go (about)

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