mirror of
https://github.com/0rangebananaspy/authelia.git
synced 2024-09-14 22:47:21 +07:00
[MISC] Introduce CryptAlgo type. (#960)
* [MISC] Introduce CryptAlgo type. It helps distinguish between the configuration representation of an algorithm and the crypt representation (6 and argon2id vs sha512 vs argon2id). * Add a description to CryptAlgo. * use const Co-authored-by: James Elliott <james-d-elliott@users.noreply.github.com>
This commit is contained in:
parent
da5c722cf8
commit
e5ccdb4449
|
@ -24,11 +24,14 @@ const (
|
||||||
// PossibleMethods is the set of all possible 2FA methods.
|
// PossibleMethods is the set of all possible 2FA methods.
|
||||||
var PossibleMethods = []string{TOTP, U2F, Push}
|
var PossibleMethods = []string{TOTP, U2F, Push}
|
||||||
|
|
||||||
|
// CryptAlgo the crypt representation of an algorithm used in the prefix of the hash.
|
||||||
|
type CryptAlgo string
|
||||||
|
|
||||||
const (
|
const (
|
||||||
// HashingAlgorithmArgon2id Argon2id hash identifier.
|
// HashingAlgorithmArgon2id Argon2id hash identifier.
|
||||||
HashingAlgorithmArgon2id = "argon2id"
|
HashingAlgorithmArgon2id CryptAlgo = "argon2id"
|
||||||
// HashingAlgorithmSHA512 SHA512 hash identifier.
|
// HashingAlgorithmSHA512 SHA512 hash identifier.
|
||||||
HashingAlgorithmSHA512 = "6"
|
HashingAlgorithmSHA512 CryptAlgo = "6"
|
||||||
)
|
)
|
||||||
|
|
||||||
// These are the default values from the upstream crypt module we use them to for GetInt
|
// These are the default values from the upstream crypt module we use them to for GetInt
|
||||||
|
|
|
@ -51,14 +51,14 @@ func NewFileUserProvider(configuration *schema.FileAuthenticationBackendConfigur
|
||||||
panic(err.Error())
|
panic(err.Error())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var cryptAlgo CryptAlgo = HashingAlgorithmArgon2id
|
||||||
// TODO: Remove this. This is only here to temporarily fix the username enumeration security flaw in #949.
|
// TODO: Remove this. This is only here to temporarily fix the username enumeration security flaw in #949.
|
||||||
// This generates a hash that should be usable to do a fake CheckUserPassword
|
// This generates a hash that should be usable to do a fake CheckUserPassword
|
||||||
algorithm := configuration.Password.Algorithm
|
|
||||||
if configuration.Password.Algorithm == sha512 {
|
if configuration.Password.Algorithm == sha512 {
|
||||||
algorithm = HashingAlgorithmSHA512
|
cryptAlgo = HashingAlgorithmSHA512
|
||||||
}
|
}
|
||||||
settings := getCryptSettings(utils.RandomString(configuration.Password.SaltLength, HashingPossibleSaltCharacters),
|
settings := getCryptSettings(utils.RandomString(configuration.Password.SaltLength, HashingPossibleSaltCharacters),
|
||||||
algorithm, configuration.Password.Iterations, configuration.Password.Memory*1024, configuration.Password.Parallelism,
|
cryptAlgo, configuration.Password.Iterations, configuration.Password.Memory*1024, configuration.Password.Parallelism,
|
||||||
configuration.Password.KeyLength)
|
configuration.Password.KeyLength)
|
||||||
data := crypt.Base64Encoding.EncodeToString([]byte(utils.RandomString(configuration.Password.KeyLength, HashingPossibleSaltCharacters)))
|
data := crypt.Base64Encoding.EncodeToString([]byte(utils.RandomString(configuration.Password.KeyLength, HashingPossibleSaltCharacters)))
|
||||||
fakeHash := fmt.Sprintf("%s$%s", settings, data)
|
fakeHash := fmt.Sprintf("%s$%s", settings, data)
|
||||||
|
@ -140,7 +140,7 @@ func (p *FileUserProvider) UpdatePassword(username string, newPassword string) e
|
||||||
return fmt.Errorf("User '%s' does not exist in database", username)
|
return fmt.Errorf("User '%s' does not exist in database", username)
|
||||||
}
|
}
|
||||||
|
|
||||||
var algorithm string
|
var algorithm CryptAlgo
|
||||||
if p.configuration.Password.Algorithm == "argon2id" {
|
if p.configuration.Password.Algorithm == "argon2id" {
|
||||||
algorithm = HashingAlgorithmArgon2id
|
algorithm = HashingAlgorithmArgon2id
|
||||||
} else if p.configuration.Password.Algorithm == sha512 {
|
} else if p.configuration.Password.Algorithm == sha512 {
|
||||||
|
|
|
@ -14,7 +14,7 @@ import (
|
||||||
// PasswordHash represents all characteristics of a password hash.
|
// PasswordHash represents all characteristics of a password hash.
|
||||||
// Authelia only supports salted SHA512 or salted argon2id method, i.e., $6$ mode or $argon2id$ mode.
|
// Authelia only supports salted SHA512 or salted argon2id method, i.e., $6$ mode or $argon2id$ mode.
|
||||||
type PasswordHash struct {
|
type PasswordHash struct {
|
||||||
Algorithm string
|
Algorithm CryptAlgo
|
||||||
Iterations int
|
Iterations int
|
||||||
Salt string
|
Salt string
|
||||||
Key string
|
Key string
|
||||||
|
@ -28,7 +28,8 @@ func ParseHash(hash string) (passwordHash *PasswordHash, err error) {
|
||||||
parts := strings.Split(hash, "$")
|
parts := strings.Split(hash, "$")
|
||||||
|
|
||||||
// This error can be ignored as it's always nil.
|
// This error can be ignored as it's always nil.
|
||||||
code, parameters, salt, key, _ := crypt.DecodeSettings(hash)
|
c, parameters, salt, key, _ := crypt.DecodeSettings(hash)
|
||||||
|
code := CryptAlgo(c)
|
||||||
h := &PasswordHash{}
|
h := &PasswordHash{}
|
||||||
|
|
||||||
h.Salt = salt
|
h.Salt = salt
|
||||||
|
@ -83,7 +84,7 @@ func ParseHash(hash string) (passwordHash *PasswordHash, err error) {
|
||||||
|
|
||||||
// HashPassword generate a salt and hash the password with the salt and a constant number of rounds.
|
// HashPassword generate a salt and hash the password with the salt and a constant number of rounds.
|
||||||
//nolint:gocyclo // TODO: Consider refactoring/simplifying, time permitting.
|
//nolint:gocyclo // TODO: Consider refactoring/simplifying, time permitting.
|
||||||
func HashPassword(password, salt, algorithm string, iterations, memory, parallelism, keyLength, saltLength int) (hash string, err error) {
|
func HashPassword(password, salt string, algorithm CryptAlgo, iterations, memory, parallelism, keyLength, saltLength int) (hash string, err error) {
|
||||||
var settings string
|
var settings string
|
||||||
|
|
||||||
if algorithm != HashingAlgorithmArgon2id && algorithm != HashingAlgorithmSHA512 {
|
if algorithm != HashingAlgorithmArgon2id && algorithm != HashingAlgorithmSHA512 {
|
||||||
|
@ -147,7 +148,7 @@ func CheckPassword(password, hash string) (ok bool, err error) {
|
||||||
return hash == expectedHash, nil
|
return hash == expectedHash, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func getCryptSettings(salt, algorithm string, iterations, memory, parallelism, keyLength int) (settings string) {
|
func getCryptSettings(salt string, algorithm CryptAlgo, iterations, memory, parallelism, keyLength int) (settings string) {
|
||||||
if algorithm == HashingAlgorithmArgon2id {
|
if algorithm == HashingAlgorithmArgon2id {
|
||||||
settings, _ = crypt.Argon2idSettings(memory, iterations, parallelism, keyLength, salt)
|
settings, _ = crypt.Argon2idSettings(memory, iterations, parallelism, keyLength, salt)
|
||||||
} else if algorithm == HashingAlgorithmSHA512 {
|
} else if algorithm == HashingAlgorithmSHA512 {
|
||||||
|
|
|
@ -34,7 +34,7 @@ var HashPasswordCmd = &cobra.Command{
|
||||||
|
|
||||||
var err error
|
var err error
|
||||||
var hash string
|
var hash string
|
||||||
var algorithm string
|
var algorithm authentication.CryptAlgo
|
||||||
|
|
||||||
if sha512 {
|
if sha512 {
|
||||||
if iterations == schema.DefaultPasswordConfiguration.Iterations {
|
if iterations == schema.DefaultPasswordConfiguration.Iterations {
|
||||||
|
|
Loading…
Reference in New Issue
Block a user