mirror of
https://github.com/Luzifer/password.git
synced 2024-11-08 17:30:10 +00:00
95 lines
2.4 KiB
Go
95 lines
2.4 KiB
Go
|
package hasher
|
||
|
|
||
|
import (
|
||
|
"crypto"
|
||
|
"crypto/rand"
|
||
|
_ "crypto/sha1"
|
||
|
_ "crypto/sha256"
|
||
|
_ "crypto/sha512"
|
||
|
|
||
|
"fmt"
|
||
|
"math/big"
|
||
|
|
||
|
"golang.org/x/crypto/bcrypt"
|
||
|
|
||
|
"github.com/tredoe/osutil/user/crypt"
|
||
|
_ "github.com/tredoe/osutil/user/crypt/apr1_crypt"
|
||
|
_ "github.com/tredoe/osutil/user/crypt/sha256_crypt"
|
||
|
_ "github.com/tredoe/osutil/user/crypt/sha512_crypt"
|
||
|
)
|
||
|
|
||
|
type hasherFunc func(password string) (string, error)
|
||
|
|
||
|
var (
|
||
|
implementations = map[string]hasherFunc{
|
||
|
"htpasswd_apr1": implHTAPR1,
|
||
|
"htpasswd_bcrypt": implBcrypt,
|
||
|
"htpasswd_sha256": implHTSHA256,
|
||
|
"htpasswd_sha512": implHTSHA512,
|
||
|
"sha1": implSHA1,
|
||
|
"sha256": implSHA256,
|
||
|
"sha512": implSHA512,
|
||
|
}
|
||
|
|
||
|
saltSet = []byte(`abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789./`)
|
||
|
saltSize = 12
|
||
|
)
|
||
|
|
||
|
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, err
|
||
|
}
|
||
|
|
||
|
result[name] = h
|
||
|
}
|
||
|
|
||
|
return result, nil
|
||
|
}
|
||
|
|
||
|
func getSalt() ([]byte, error) {
|
||
|
salt := make([]byte, saltSize)
|
||
|
saltSetLength := big.NewInt(int64(len(saltSet)))
|
||
|
|
||
|
for i := 0; i < saltSize; i++ {
|
||
|
pos, err := rand.Int(rand.Reader, saltSetLength)
|
||
|
if err != nil {
|
||
|
return nil, err
|
||
|
}
|
||
|
salt[i] = saltSet[pos.Int64()]
|
||
|
}
|
||
|
|
||
|
return salt, nil
|
||
|
}
|
||
|
|
||
|
func implBcrypt(password string) (string, error) {
|
||
|
bc, err := bcrypt.GenerateFromPassword([]byte(password), bcrypt.DefaultCost)
|
||
|
return string(bc), err
|
||
|
}
|
||
|
|
||
|
func genericHT(password, prefix string) (string, error) {
|
||
|
salt, err := getSalt()
|
||
|
if err != nil {
|
||
|
return "", err
|
||
|
}
|
||
|
|
||
|
return crypt.NewFromHash(prefix+string(salt)).Generate([]byte(password), append([]byte(prefix), salt...))
|
||
|
}
|
||
|
|
||
|
func implHTAPR1(password string) (string, error) { return genericHT(password, "$apr1$") }
|
||
|
func implHTSHA256(password string) (string, error) { return genericHT(password, "$5$") }
|
||
|
func implHTSHA512(password string) (string, error) { return genericHT(password, "$6$") }
|
||
|
|
||
|
func generic(password string, h crypto.Hash) (string, error) {
|
||
|
w := h.New()
|
||
|
w.Write([]byte(password))
|
||
|
return fmt.Sprintf("%x", w.Sum(nil)), nil
|
||
|
}
|
||
|
|
||
|
func implSHA1(password string) (string, error) { return generic(password, crypto.SHA1) }
|
||
|
func implSHA256(password string) (string, error) { return generic(password, crypto.SHA256) }
|
||
|
func implSHA512(password string) (string, error) { return generic(password, crypto.SHA512) }
|