/
crypto-functions.go
123 lines (90 loc) · 1.93 KB
/
crypto-functions.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
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
package wphash
import (
"crypto/md5"
"math"
"math/rand"
"strings"
"time"
)
const ITOA64 = "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
const ITERATION_COUNT_LOG2 = 8
const POSSIBLE_CHARS = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"
func init() {
rand.Seed(time.Now().UTC().UnixNano())
}
func encode64(input string, count int) string {
output := ""
i := 0
for ok := true; ok; ok = (i < count) {
value := uint(input[i])
i++
output += string(ITOA64[value&0x3f])
if i < count {
value |= uint(input[i]) << 8
}
output += string(ITOA64[(value>>6)&0x3f])
if i >= count {
break
}
i++
if i < count {
value |= uint(input[i]) << 16
}
output += string(ITOA64[(value>>12)&0x3f])
if i >= count {
break
}
i++
output += string(ITOA64[(value>>18)&0x3f])
}
return output
}
func generatePrivateSalt(input string) string {
output := "$P$"
output += string(ITOA64[int(math.Min(ITERATION_COUNT_LOG2+5, 30))])
output += encode64(input, 6)
return output
}
func cryptPrivate(password string, setting string) string {
output := "*0"
if setting[0:2] == output {
output = "*1"
}
if setting[0:3] != "$P$" {
return output
}
countLog2 := uint(strings.Index(ITOA64, string(setting[3])))
if countLog2 < 7 || countLog2 > 30 {
return output
}
count := 1 << countLog2
salt := setting[4:12]
if len(salt) != 8 {
return output
}
hash := hashString(salt + password)
for count != 0 {
hash = hashString(hash + password)
count--
}
output = setting[0:12]
output += encode64(hash, 16)
return output
}
func hashString(data string) string {
return hash([]byte(data))
}
func hash(data []byte) string {
hasher := md5.New()
hasher.Write(data)
return string(hasher.Sum(nil))
}
func sixCharRandom() string {
text := ""
i := 0
for i < 6 {
text += string(POSSIBLE_CHARS[int(math.Floor(rand.Float64()*float64(len(POSSIBLE_CHARS))))])
i++
}
return text
}