package pwhash import ( "crypto/hkdf" "crypto/pbkdf2" "crypto/sha256" "crypto/sha512" "fmt" ) const SaltLen = sha256.Size + sha512.Size const defaultIterations = 3670016 // from cmd/finditers func HashIter(password string, salt []byte, iter int) ([]byte, error) { return pbkdf2.Key(sha256.New, password, salt, iter, sha256.Size) } func Hash(password string, salt []byte) (key, pwHash []byte, err error) { if len(salt) != SaltLen { return nil, nil, fmt.Errorf("bad salt size") } hashedPassword, err := HashIter(password, salt[:sha256.Size], defaultIterations) if err != nil { return nil, nil, err } key, err = hkdf.Extract(sha512.New, hashedPassword, salt[sha256.Size:]) if err != nil { return nil, nil, err } pwHash, err = hkdf.Expand(sha512.New, key, "auth", sha512.Size) if err != nil { return nil, nil, err } return key, pwHash, nil }