hash加密密码,验证密码
我这里是兼容了django的默认加密密码,可以从获取出来直接验证
package collections
import (
"crypto/sha256"
"encoding/base64"
"fmt"
"strconv"
"strings"
"math/rand"
"golang.org/x/crypto/pbkdf2"
)
const Iterations int = 390000
const KeyLen int = sha256.Size
var letters = []rune("123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ")
// 输入字符长度,生成随机字符串
func randStr(n int) string {
b := make([]rune, n)
for i := range b {
b[i] = letters[rand.Intn(len(letters))]
}
return string(b)
}
// storedHash是查询出来的用户hash, password是输入的密码,进行比较输入是否正确
func GeneratePasswordHash(password string) (string, error) {
salt := randStr(22)
hash := pbkdf2.Key([]byte(password), []byte(salt), Iterations, sha256.Size, sha256.New)
hashBase64 := base64.StdEncoding.EncodeToString(hash)
result := fmt.Sprintf("pbkdf2_sha256$%d$%s$%s", Iterations, salt, hashBase64)
return result, nil
}
func VerifyPassword(storedHash string, password string) (bool, error) {
// 分解 hash 字符串
parts := strings.Split(storedHash, "$")
if len(parts) != 4 {
return false, fmt.Errorf("invalid hash format")
}
// 提取迭代次数、盐值、哈希值
iterations, err := strconv.Atoi(parts[1])
if err != nil {
return false, fmt.Errorf("invalid iteration count")
}
salt := []byte(parts[2])
storedHashBytes, err := base64.StdEncoding.DecodeString(parts[3])
if err != nil {
return false, fmt.Errorf("invalid hash encoding")
}
// 使用 PBKDF2 计算哈希值
computedHash := pbkdf2.Key([]byte(password), salt, iterations, sha256.Size, sha256.New)
computedHashStr := string(computedHash)
storedHashStr := string(storedHashBytes)
// 比较计算出的哈希与存储的哈希
if computedHashStr == storedHashStr {
return true, nil
}
return false, nil
}
// func Test() {
// // hash := `pbkdf2_sha256\$390000$iI5iVFnZMDVmL2L7Bw5nL0$f7O8ArVr1XJoaK/Uwop43GHH1iPy22GygkeWqU2nxU0=`
// // hash := `pbkdf2_sha256$390000$SDFD21342DSsdf$VCEqR0t7zF0Eyw7s3DiFrfivcT/c4ln9Ov3QjvcwZis=`
// hash := `pbkdf2_sha256$390000$ZmG3cbHttPh15bJT$PpmdJMB9xkt30xkKsZIU7VpIhok6NT+9K2Z/91LjHrc=`
// password := "chenhaifeng"
// valid, err := verifyPassword(hash, password)
// if err != nil {
// fmt.Println("Error:", err)
// } else if valid {
// fmt.Println("Password is valid!")
// pwdHash, _ := generatePasswordHash(password)
// fmt.Println(pwdHash)
// } else {
// fmt.Println("Invalid password")
// }
// }