/
password.go
73 lines (61 loc) · 1.54 KB
/
password.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
package admin
import (
"crypto/sha256"
"encoding/base64"
"fmt"
"math/rand"
"strings"
"time"
)
// 密码生成器接口
type Password interface {
Hash(password []byte) []byte
Verify(password, hash []byte) bool
}
// 注册密码生成器
func RegisterPassword(password Password) {
Passworder = password
}
var Passworder Password
// 默认密码生成器
type PasswordDefault struct {
}
func (p *PasswordDefault) Hash(password []byte) []byte {
return p.hashWithSalt(password, p.salt())
}
func (p *PasswordDefault) hashWithSalt(password, salt []byte) []byte {
sha := p.sha265(append(p.sha265(append(password, salt...)), salt...))
src := append(
sha[:],
append([]byte("|"), salt...)...
)
return []byte(base64.StdEncoding.EncodeToString(src))
}
func (p *PasswordDefault) Verify(password, hash []byte) bool {
dst := make([]byte, 0)
dst, err := base64.StdEncoding.DecodeString(string(hash))
if err != nil {
return false
}
hashItem := strings.Split(string(dst), "|")
if len(hashItem) != 2 {
return false
}
return string(hash) == string(p.hashWithSalt(password, []byte(hashItem[1])))
}
func (p *PasswordDefault) salt() []byte {
str := "0123456789abcdefghijklmnopqrstuvwxyz"
bytes := []byte(str)
result := make([]byte, 0)
r := rand.New(rand.NewSource(time.Now().UnixNano()))
for i := 0; i < 8; i++ {
result = append(result, bytes[r.Intn(len(bytes))])
}
return result
}
func (p *PasswordDefault) sha265(data []byte) []byte {
return []byte(fmt.Sprintf("%x", sha256.Sum256(data)))
}
func init() {
RegisterPassword(new(PasswordDefault))
}