package libPassword import "golang.org/x/crypto/pbkdf2" import "hash" import "strconv" import "encoding/base64" import "crypto/sha1" import "crypto/sha256" import "crypto/sha512" import "crypto/rand" import "fmt" import "strings" const ( salt_length = 8 hash_length = 20 interations = 10000 hashfunc string = "sha256" ) var hashlib = map[string]func() hash.Hash{ "sha1": sha1.New, "sha256": sha256.New, "sha512": sha512.New, } func Validate(hash, password string) (output, replace bool) { parts := strings.Split(hash, "$") if len(parts) == 3 { return false, false } cur_iter, err := strconv.Atoi(parts[1]) if err != nil { return false, false } hashfunc_c := strings.Split(parts[0], "_")[1] replace = (hashfunc_c != hashfunc) dk := pbkdf2.Key([]byte(password), []byte(parts[2]), cur_iter, len(parts[3])-8, hashlib[hashfunc_c]) x := fmt.Sprintf("pbkdf2_%s$%s$%s$%s", hashfunc_c, parts[1], parts[2], base64.StdEncoding.EncodeToString(dk)) output = (x == hash) return } func GenerateRandomString(n int) (string, error) { b := make([]byte, n) _, err := rand.Read(b) if err != nil { return "", err } return base64.URLEncoding.EncodeToString(b), nil } func NewHash(password string) string { salt, _ := GenerateRandomString(salt_length) dk := pbkdf2.Key([]byte(password), []byte(salt), interations, hash_length, hashlib[hashfunc]) return fmt.Sprintf("pbkdf2_%s$%d$%s$%s", hashfunc, interations, salt, base64.StdEncoding.EncodeToString(dk)) }