80 lines
2.1 KiB
Go
80 lines
2.1 KiB
Go
package password
|
|
|
|
import (
|
|
"crypto/rand"
|
|
"encoding/hex"
|
|
"fmt"
|
|
"strings"
|
|
|
|
"golang.org/x/crypto/bcrypt"
|
|
"golang.org/x/crypto/scrypt"
|
|
)
|
|
|
|
// ******************** scrypt ********************
|
|
|
|
// ScryptHashPassword scrypt 加密
|
|
// password 原始密码
|
|
func ScryptHashPassword(password string) (string, error) {
|
|
// example for making salt - https://play.golang.org/p/_Aw6WeWC42I
|
|
salt := make([]byte, 32)
|
|
_, err := rand.Read(salt)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
|
|
// using recommended cost parameters from - https://godoc.org/golang.org/x/crypto/scrypt
|
|
shash, err := scrypt.Key([]byte(password), salt, 32768, 8, 1, 32)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
|
|
// return hex-encoded string with salt appended to password
|
|
hashedPW := fmt.Sprintf("%s.%s", hex.EncodeToString(shash), hex.EncodeToString(salt))
|
|
|
|
return hashedPW, nil
|
|
}
|
|
|
|
// ScryptComparePassword 判断密码是否正确
|
|
// storedPassword 加密密码
|
|
// suppliedPassword 原始密码
|
|
func ScryptComparePassword(storedPassword string, suppliedPassword string) error {
|
|
pwsalt := strings.Split(storedPassword, ".")
|
|
|
|
// check supplied password salted with hash
|
|
salt, err := hex.DecodeString(pwsalt[1])
|
|
|
|
if err != nil {
|
|
return fmt.Errorf("unable to verify user password")
|
|
}
|
|
|
|
shash, err := scrypt.Key([]byte(suppliedPassword), salt, 32768, 8, 1, 32)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
if hex.EncodeToString(shash) == pwsalt[0] {
|
|
return nil
|
|
}
|
|
|
|
return fmt.Errorf("password error")
|
|
}
|
|
|
|
// ******************** bcrypt ********************
|
|
|
|
// BcryptHashPassword bcrypt 加密
|
|
// password 原始密码
|
|
func BcryptHashPassword(password string) (string, error) {
|
|
hashedPassword, err := bcrypt.GenerateFromPassword([]byte(password), bcrypt.DefaultCost)
|
|
if err != nil {
|
|
return "", fmt.Errorf("failed to hash password: %w", err)
|
|
}
|
|
return string(hashedPassword), nil
|
|
}
|
|
|
|
// BcryptComparePassword 判断密码是否正确
|
|
// hashedPassword 加密密码
|
|
// password 原始密码
|
|
func BcryptComparePassword(hashedPassword string, password string) error {
|
|
return bcrypt.CompareHashAndPassword([]byte(hashedPassword), []byte(password))
|
|
}
|