mirror of
https://github.com/charlienet/go-mixed.git
synced 2025-07-17 16:12:42 +08:00
密码评估,密码加密
This commit is contained in:
44
password/password_evaluate.go
Normal file
44
password/password_evaluate.go
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
package password
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"regexp"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
LevelD = iota
|
||||||
|
LevelC
|
||||||
|
LevelB
|
||||||
|
LevelA
|
||||||
|
LevelS
|
||||||
|
)
|
||||||
|
|
||||||
|
var patterns = []*regexp.Regexp{
|
||||||
|
regexp.MustCompile(`[0-9]+`), // 数字
|
||||||
|
regexp.MustCompile(`[a-z]+`), // 小字字母
|
||||||
|
regexp.MustCompile(`[A-Z]+`), // 大写字母
|
||||||
|
regexp.MustCompile(`[~!@#$%^&*?_-]+`), // 特殊符号
|
||||||
|
}
|
||||||
|
|
||||||
|
func PasswordEvaluate(minLength, maxLength int, minLevel int, password string) error {
|
||||||
|
// 首先校验密码长度是否在范围内
|
||||||
|
if len(password) < minLength {
|
||||||
|
return fmt.Errorf("无效密码: 密码长度小于%d个字符", minLength)
|
||||||
|
}
|
||||||
|
if len(password) > maxLength {
|
||||||
|
return fmt.Errorf("无效密码: 密码的长度大于%d个字符", maxLength)
|
||||||
|
}
|
||||||
|
|
||||||
|
var level int = LevelD
|
||||||
|
for _, pattern := range patterns {
|
||||||
|
if pattern.MatchString(password) {
|
||||||
|
level++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 如果最终密码强度低于要求的最低强度,返回并报错
|
||||||
|
if level < minLevel {
|
||||||
|
return fmt.Errorf("密码强度不满足当前策略要求。")
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
22
password/salt_password.go
Normal file
22
password/salt_password.go
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
package password
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/charlienet/go-mixed/bytesconv"
|
||||||
|
"golang.org/x/crypto/bcrypt"
|
||||||
|
)
|
||||||
|
|
||||||
|
func GenerateFromPassword(pwd []byte) (string, error) {
|
||||||
|
hash, err := bcrypt.GenerateFromPassword(pwd, bcrypt.DefaultCost)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
return bytesconv.BytesToString(hash), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func ComparePassword(hashed string, plain []byte) bool {
|
||||||
|
byteHash := bytesconv.StringToBytes(hashed)
|
||||||
|
err := bcrypt.CompareHashAndPassword(byteHash, plain)
|
||||||
|
|
||||||
|
return err == nil
|
||||||
|
}
|
23
password/salt_password_test.go
Normal file
23
password/salt_password_test.go
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
package password
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestPassword(t *testing.T) {
|
||||||
|
pwd := "123456"
|
||||||
|
|
||||||
|
h1, _ := GenerateFromPassword([]byte(pwd))
|
||||||
|
t.Log(ComparePassword(h1, []byte(pwd)))
|
||||||
|
|
||||||
|
for i := 0; i < 100; i++ {
|
||||||
|
h, err := GenerateFromPassword([]byte(pwd))
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
assert.True(t, ComparePassword(h, []byte(pwd)))
|
||||||
|
}
|
||||||
|
}
|
Reference in New Issue
Block a user