-
Notifications
You must be signed in to change notification settings - Fork 1
/
signer.go
199 lines (166 loc) · 4.59 KB
/
signer.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
package sign
import (
"fmt"
"github.com/gogf/gf/util/grand"
"net/url"
"sort"
"strconv"
"strings"
)
// CryptoFunc 签名加密函数
type CryptoFunc func(secretKey string, args string) []byte
// Signer define
type Signer struct {
*DefaultKeyName
body url.Values // 签名参数体
bodyPrefix string // 参数体前缀
bodySuffix string // 参数体后缀
splitChar string // 前缀、后缀分隔符号
secretKey string // 签名密钥
cryptoFunc CryptoFunc
}
// NewSigner 实例化 Signer
func NewSigner(cryptoFunc CryptoFunc) *Signer {
return &Signer{
DefaultKeyName: newDefaultKeyName(),
body: make(url.Values),
bodyPrefix: "",
bodySuffix: "",
splitChar: "",
cryptoFunc: cryptoFunc,
}
}
// NewSignerMd5 md5加密算法
func NewSignerMd5() *Signer {
return NewSigner(Md5Sign)
}
// NewSignerHmac hmac加密算法
func NewSignerHmac() *Signer {
return NewSigner(HmacSign)
}
// NewSignerAes aes对称加密算法
func NewSignerAes() *Signer {
return NewSigner(AesSign)
}
// SetBody 设置整个参数体Body对象。
func (s *Signer) SetBody(body url.Values) {
for k, v := range body {
s.body[k] = v
}
}
// GetBody 返回Body内容
func (s *Signer) GetBody() url.Values {
return s.body
}
// AddBody 添加签名体字段和值
func (s *Signer) AddBody(key string, value string) *Signer {
return s.AddBodies(key, []string{value})
}
// AddBodies add value to body
func (s *Signer) AddBodies(key string, value []string) *Signer {
s.body[key] = value
return s
}
// SetTimeStamp 设置时间戳参数
func (s *Signer) SetTimeStamp(ts int64) *Signer {
return s.AddBody(s.Timestamp, strconv.FormatInt(ts, 10))
}
// GetTimeStamp 获取TimeStamp
func (s *Signer) GetTimeStamp() string {
return s.body.Get(s.Timestamp)
}
// SetNonceStr 设置随机字符串参数
func (s *Signer) SetNonceStr(nonce string) *Signer {
return s.AddBody(s.NonceStr, nonce)
}
// GetNonceStr 返回NonceStr字符串
func (s *Signer) GetNonceStr() string {
return s.body.Get(s.NonceStr)
}
// SetAppID 设置AppId参数
func (s *Signer) SetAppID(appID string) *Signer {
return s.AddBody(s.AppID, appID)
}
// GetAppID get app id
func (s *Signer) GetAppID() string {
return s.body.Get(s.AppID)
}
// RandNonceStr 自动生成16位随机字符串参数
func (s *Signer) RandNonceStr() *Signer {
return s.SetNonceStr(grand.S(16))
}
// SetSignBodyPrefix 设置签名字符串的前缀字符串
func (s *Signer) SetSignBodyPrefix(prefix string) *Signer {
s.bodyPrefix = prefix
return s
}
// SetSignBodySuffix 设置签名字符串的后缀字符串
func (s *Signer) SetSignBodySuffix(suffix string) *Signer {
s.bodySuffix = suffix
return s
}
// SetSplitChar 设置前缀、后缀与签名体之间的分隔符号。默认为空字符串
func (s *Signer) SetSplitChar(split string) *Signer {
s.splitChar = split
return s
}
// SetAppSecret 设置签名密钥
func (s *Signer) SetAppSecret(appSecret string) *Signer {
s.secretKey = appSecret
return s
}
// SetAppSecretWrapBody 在签名参数体的首部和尾部,拼接AppSecret字符串。
func (s *Signer) SetAppSecretWrapBody(appSecret string) *Signer {
s.SetSignBodyPrefix(appSecret)
s.SetSignBodySuffix(appSecret)
return s.SetAppSecret(appSecret)
}
// GetSignBodyString 获取用于签名的原始字符串
func (s *Signer) GetSignBodyString() string {
return s.MakeRawBodyString()
}
// MakeRawBodyString 获取用于签名的原始字符串
func (s *Signer) MakeRawBodyString() string {
return s.bodyPrefix + s.splitChar + s.getSortedBodyString() + s.splitChar + s.bodySuffix
}
// GetSignedQuery 获取带签名参数的查询字符串
func (s *Signer) GetSignedQuery() string {
return s.MakeSignedQuery()
}
// MakeSignedQuery 获取带签名参数的字符串
func (s *Signer) MakeSignedQuery() string {
body := s.getSortedBodyString()
sign := s.GetSignature()
return body + "&" + s.Sign + "=" + sign
}
// GetSignature 获取签名
func (s *Signer) GetSignature() string {
return s.MakeSign()
}
// MakeSign 生成签名
func (s *Signer) MakeSign() string {
sign := fmt.Sprintf("%x", s.cryptoFunc(s.secretKey, s.GetSignBodyString()))
return sign
}
func (s *Signer) getSortedBodyString() string {
return SortKVPairs(s.body)
}
// SortKVPairs 将Map的键值对,按字典顺序拼接成字符串
func SortKVPairs(m url.Values) string {
size := len(m)
if size == 0 {
return ""
}
keys := make([]string, size)
idx := 0
for k := range m {
keys[idx] = k
idx++
}
sort.Strings(keys)
pairs := make([]string, size)
for i, key := range keys {
pairs[i] = key + "=" + strings.Join(m[key], ",")
}
return strings.Join(pairs, "&")
}