@@ -0,0 +1,104 @@
|
||||
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
|
||||
}
|
||||
Reference in New Issue
Block a user