1
0
mirror of https://github.com/Luzifer/password.git synced 2024-09-19 10:22:56 +00:00
password/hasher/hasher.go

75 lines
2.1 KiB
Go
Raw Permalink Normal View History

// Package hasher contains methods to generate hashes for a given password
package hasher
import (
"crypto/sha256"
"crypto/sha512"
"fmt"
"hash"
"github.com/GehirnInc/crypt"
"github.com/GehirnInc/crypt/apr1_crypt"
"github.com/GehirnInc/crypt/sha256_crypt"
"github.com/GehirnInc/crypt/sha512_crypt"
"golang.org/x/crypto/bcrypt"
)
type hasherFunc func(password string) (string, error)
var implementations = map[string]hasherFunc{
"htpasswd_apr1": implHTAPR1,
"htpasswd_bcrypt": implBcrypt,
"htpasswd_sha256": implHTSHA256,
"htpasswd_sha512": implHTSHA512,
"sha256": implSHA256,
"sha512": implSHA512,
}
// GetHashMap generates a map of hashes of the given password
func GetHashMap(password string) (map[string]string, error) {
result := map[string]string{}
for name, hf := range implementations {
h, err := hf(password)
if err != nil {
return nil, fmt.Errorf("hashing %s: %w", name, err)
}
result[name] = h
}
return result, nil
}
func generic(h hash.Hash, password string) (_ string, err error) {
if _, err = h.Write([]byte(password)); err != nil {
return "", fmt.Errorf("writing password to hash: %w", err)
}
return fmt.Sprintf("%x", h.Sum(nil)), nil
}
func genericHT(c crypt.Crypter, password string) (string, error) {
h, err := c.Generate([]byte(password), nil) // Salt is auto-generated
if err != nil {
return "", fmt.Errorf("generating hash: %w", err)
}
return h, nil
}
func implBcrypt(password string) (string, error) {
bc, err := bcrypt.GenerateFromPassword([]byte(password), bcrypt.DefaultCost)
if err != nil {
return "", fmt.Errorf("generating bcrypt hash: %w", err)
}
return string(bc), nil
}
func implHTAPR1(password string) (string, error) { return genericHT(apr1_crypt.New(), password) }
func implHTSHA256(password string) (string, error) { return genericHT(sha256_crypt.New(), password) }
func implHTSHA512(password string) (string, error) { return genericHT(sha512_crypt.New(), password) }
func implSHA256(password string) (string, error) { return generic(sha256.New(), password) }
func implSHA512(password string) (string, error) { return generic(sha512.New(), password) }