-
Notifications
You must be signed in to change notification settings - Fork 1
/
srp6.go
221 lines (192 loc) · 4.89 KB
/
srp6.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
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
package srp6
import (
"bytes"
"crypto/rand"
"crypto/sha1"
"errors"
"fmt"
"math/big"
"strings"
)
const (
N = "894B645E89E1535BBDAD5B8B290650530801B18EBFBF5E8FAB3C82872A3E9BB7"
G = "7"
Num = 32
)
// 是一个用于计算SHA-1哈希值的方法
func ToHashSHA(value []byte) []byte {
hash := sha1.New()
hash.Write(value)
result := hash.Sum(nil)
return result
}
// 对负数的大整数执行补码操作
func MakePositive(inValue *big.Int) *big.Int {
if inValue.Sign() < 0 {
// 转换为字节数组
oldBytes := inValue.Bytes()
newBytes := make([]byte, len(oldBytes)+1)
copy(newBytes, oldBytes)
// 在最高位补0
newBytes[len(oldBytes)] = 0
return new(big.Int).SetBytes(newBytes)
}
return inValue
}
// 将大整数转换为无符号字节数组
func ToUnsignedByteArray(bigInt *big.Int) []byte {
bigIntByteArray := bigInt.Bytes()
if len(bigIntByteArray) > 0 && bigIntByteArray[len(bigIntByteArray)-1] == 0 {
// 创建一个缩短的字节数组
shortenedByteArray := make([]byte, len(bigIntByteArray)-1)
for i := 0; i < len(shortenedByteArray); i++ {
shortenedByteArray[i] = bigIntByteArray[i]
}
bigIntByteArray = shortenedByteArray
}
return bigIntByteArray
}
// 连接多个字节数组
func Concatenate(arrays ...[]byte) []byte {
var length int
for _, arr := range arrays {
if arr != nil {
length += len(arr)
}
}
result := make([]byte, length)
length = 0
for _, arr := range arrays {
if arr != nil {
copy(result[length:], arr)
length += len(arr)
}
}
return result
}
// 将大整数转换为固定长度的字节数组
func FromBigSalt(value *big.Int) []byte {
_bytes := value.Bytes()
if len(_bytes) < Num {
res := make([]byte, Num)
copy(res, _bytes)
return res
} else if len(_bytes) > Num {
bts := make([]byte, Num)
copy(bts, _bytes[:Num])
return bts
}
return _bytes
}
// 将二进制字符串转换为大整数
func CreateBigInteger(text string) *big.Int {
isEvenLength := len(text)%2 == 0
length := len(text)/2 + func(isEven bool) int {
if isEven {
return 0
}
return 1
}(isEvenLength)
result := make([]byte, length+1)
for i := 0; i < length; i++ {
j := len(text) - i*2 - 1
ch := '0'
if j > 0 {
ch = rune(text[j-1])
}
_bytes := GetHexadecimalByte(byte(ch), text[j])
result[i] = _bytes
}
result[length] = 0
res := new(big.Int).SetBytes(reverseBytes(result))
return res
}
// 计算两个十六进制字符的字节值
func GetHexadecimalByte(ch1, ch2 byte) byte {
upperByte, _ := HexadecimalCharToByte(ch1)
lowByte, _ := HexadecimalCharToByte(ch2)
upperByte = upperByte << 4
return upperByte | lowByte
}
// 将十六进制字符转换为字节
func HexadecimalCharToByte(ch byte) (byte, error) {
switch {
case '0' <= ch && ch <= '9':
return ch - '0', nil
case 'a' <= ch && ch <= 'f':
return ch - 'a' + 10, nil
case 'A' <= ch && ch <= 'F':
return ch - 'A' + 10, nil
default:
return 0, errors.New("invalid hexadecimal character")
}
}
// 检查Salt和Verifier是否匹配
func CheckSaltVerifier(user, pass string, oldSalt, oldVerifier []byte) bool {
value := fmt.Sprintf("%s:%s", strings.ToUpper(user), strings.ToUpper(pass))
hash := ToHashSHA([]byte(value))
//根据老的salt生成新的ver
newVer := MakeVerifier(hash[:], oldSalt)
//转2进制
newVerifier := FromBigSalt(newVer)
//翻转
ReverseByteArray(newVerifier)
//做对比
return bytes.Equal(oldVerifier, newVerifier)
}
// 将字节数组转换为十六进制字符串
func ToHexString(bytes []byte) string {
hexString := ""
for _, b := range bytes {
hexString += fmt.Sprintf("%02X", b)
}
return hexString
}
// 反转字节数组
func ReverseByteArray(bytes []byte) {
for i, j := 0, len(bytes)-1; i < j; i, j = i+1, j-1 {
bytes[i], bytes[j] = bytes[j], bytes[i]
}
}
// 改为小端排序
func reverseBytes(bytes []byte) []byte {
reversed := make([]byte, len(bytes))
for i, j := 0, len(bytes)-1; i < len(bytes); i, j = i+1, j-1 {
reversed[i] = bytes[j]
}
return reversed
}
// 创建Verifier
func MakeVerifier(hash, salt []byte) *big.Int {
accHash := ToHexString(hash)
btr := CreateBigInteger(accHash)
bArray := ToUnsignedByteArray(btr)
//ReverseByteArray(bArray)
saltBytes := Concatenate(salt, bArray)
resSaltBytes := ToHashSHA(saltBytes)
ReverseByteArray(resSaltBytes)
hs := ToHexString(resSaltBytes)
saltedIdentityHash := CreateBigInteger(hs)
generator := CreateBigInteger(G)
modulus := CreateBigInteger(N)
verifier := new(big.Int).Exp(generator, saltedIdentityHash, modulus)
return verifier
}
// 将字节数组转换为大整数
func ToBigInteger(data []byte) *big.Int {
return new(big.Int).SetBytes(data)
}
func MakeSalt() *big.Int {
salt := CreateBigIntegerSalt()
return salt
}
// 生成一个随机的大整数
func CreateBigIntegerSalt() *big.Int {
randomBytes := make([]byte, Num)
_, err := rand.Read(randomBytes)
if err != nil {
panic(err)
}
bigInt := new(big.Int).SetBytes(randomBytes)
return MakePositive(bigInt)
}