feat: bcrypt cost provisioning

This commit is contained in:
GreyXor
2025-08-06 10:08:29 +02:00
parent c436485767
commit e09d4bd036
2 changed files with 16 additions and 11 deletions

View File

@@ -116,7 +116,7 @@ func cmdHashPassword(fs caddycmd.Flags) (int, error) {
var hashString string var hashString string
switch algorithm { switch algorithm {
case "bcrypt": case "bcrypt":
hash, err = BcryptHash{cost: bcryptCost}.Hash(plaintext) hash, err = BcryptHash{Cost: bcryptCost}.Hash(plaintext)
hashString = string(hash) hashString = string(hash)
default: default:
return caddy.ExitCodeFailedStartup, fmt.Errorf("unrecognized hash algorithm: %s", algorithm) return caddy.ExitCodeFailedStartup, fmt.Errorf("unrecognized hash algorithm: %s", algorithm)

View File

@@ -30,9 +30,9 @@ const defaultBcryptCost = 14
// BcryptHash implements the bcrypt hash. // BcryptHash implements the bcrypt hash.
type BcryptHash struct { type BcryptHash struct {
// cost is the bcrypt hashing difficulty factor (work factor). // Cost is the bcrypt hashing difficulty factor (work factor).
// Higher values increase computation time and security. // Higher values increase computation time and security.
cost int Cost int
} }
// CaddyModule returns the Caddy module information. // CaddyModule returns the Caddy module information.
@@ -43,6 +43,15 @@ func (BcryptHash) CaddyModule() caddy.ModuleInfo {
} }
} }
// Provision sets up default values.
func (b *BcryptHash) Provision(ctx caddy.Context) error {
if b.Cost < bcrypt.MinCost || b.Cost > bcrypt.MaxCost {
b.Cost = defaultBcryptCost
}
return nil
}
// Compare compares passwords. // Compare compares passwords.
func (BcryptHash) Compare(hashed, plaintext []byte) (bool, error) { func (BcryptHash) Compare(hashed, plaintext []byte) (bool, error) {
err := bcrypt.CompareHashAndPassword(hashed, plaintext) err := bcrypt.CompareHashAndPassword(hashed, plaintext)
@@ -57,12 +66,7 @@ func (BcryptHash) Compare(hashed, plaintext []byte) (bool, error) {
// Hash hashes plaintext using a random salt. // Hash hashes plaintext using a random salt.
func (b BcryptHash) Hash(plaintext []byte) ([]byte, error) { func (b BcryptHash) Hash(plaintext []byte) ([]byte, error) {
cost := b.cost return bcrypt.GenerateFromPassword(plaintext, b.Cost)
if cost < bcrypt.MinCost || cost > bcrypt.MaxCost {
cost = defaultBcryptCost
}
return bcrypt.GenerateFromPassword(plaintext, cost)
} }
// FakeHash returns a fake hash. // FakeHash returns a fake hash.
@@ -74,6 +78,7 @@ func (BcryptHash) FakeHash() []byte {
// Interface guards // Interface guards
var ( var (
_ Comparer = (*BcryptHash)(nil) _ Comparer = (*BcryptHash)(nil)
_ Hasher = (*BcryptHash)(nil) _ Hasher = (*BcryptHash)(nil)
_ caddy.Provisioner = (*BcryptHash)(nil)
) )