105 lines
2.5 KiB
Go
105 lines
2.5 KiB
Go
package utils
|
|
|
|
import (
|
|
"errors"
|
|
"regexp"
|
|
"unicode"
|
|
|
|
"golang.org/x/crypto/bcrypt"
|
|
)
|
|
|
|
var (
|
|
ErrPasswordTooShort = errors.New("密码长度至少为8个字符")
|
|
ErrPasswordNoUpper = errors.New("密码必须包含至少一个大写字母")
|
|
ErrPasswordNoLower = errors.New("密码必须包含至少一个小写字母")
|
|
ErrPasswordNoDigit = errors.New("密码必须包含至少一个数字")
|
|
ErrPasswordNoSpecial = errors.New("密码必须包含至少一个特殊字符")
|
|
ErrPasswordCommon = errors.New("密码不能是常见弱密码")
|
|
ErrPasswordSameChars = errors.New("密码不能全部是相同字符")
|
|
)
|
|
|
|
// 常见弱密码列表
|
|
var commonPasswords = []string{
|
|
"password", "12345678", "123456789", "1234567890",
|
|
"qwerty", "abc123", "password123", "admin123",
|
|
"123456", "1234567", "12345", "1234",
|
|
"admin", "root", "user", "test",
|
|
}
|
|
|
|
// ValidatePasswordStrength 验证密码强度
|
|
func ValidatePasswordStrength(password string) error {
|
|
// 检查长度
|
|
if len(password) < 8 {
|
|
return ErrPasswordTooShort
|
|
}
|
|
|
|
// 检查是否全部相同字符
|
|
allSame := true
|
|
for i := 1; i < len(password); i++ {
|
|
if password[i] != password[0] {
|
|
allSame = false
|
|
break
|
|
}
|
|
}
|
|
if allSame {
|
|
return ErrPasswordSameChars
|
|
}
|
|
|
|
// 检查是否包含大写字母
|
|
hasUpper := false
|
|
// 检查是否包含小写字母
|
|
hasLower := false
|
|
// 检查是否包含数字
|
|
hasDigit := false
|
|
// 检查是否包含特殊字符
|
|
hasSpecial := false
|
|
|
|
for _, char := range password {
|
|
switch {
|
|
case unicode.IsUpper(char):
|
|
hasUpper = true
|
|
case unicode.IsLower(char):
|
|
hasLower = true
|
|
case unicode.IsDigit(char):
|
|
hasDigit = true
|
|
case unicode.IsPunct(char) || unicode.IsSymbol(char):
|
|
hasSpecial = true
|
|
}
|
|
}
|
|
|
|
if !hasUpper {
|
|
return ErrPasswordNoUpper
|
|
}
|
|
if !hasLower {
|
|
return ErrPasswordNoLower
|
|
}
|
|
if !hasDigit {
|
|
return ErrPasswordNoDigit
|
|
}
|
|
if !hasSpecial {
|
|
return ErrPasswordNoSpecial
|
|
}
|
|
|
|
// 检查是否是常见弱密码
|
|
lowerPassword := regexp.MustCompile(`[^a-z]`).ReplaceAllString(password, "")
|
|
for _, common := range commonPasswords {
|
|
if lowerPassword == common {
|
|
return ErrPasswordCommon
|
|
}
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// HashPassword 加密密码
|
|
func HashPassword(password string) (string, error) {
|
|
bytes, err := bcrypt.GenerateFromPassword([]byte(password), bcrypt.DefaultCost)
|
|
return string(bytes), err
|
|
}
|
|
|
|
// CheckPassword 验证密码
|
|
func CheckPassword(password, hash string) bool {
|
|
err := bcrypt.CompareHashAndPassword([]byte(hash), []byte(password))
|
|
return err == nil
|
|
}
|