最近对接了多个第三方平台,但是都没有提供go的sdk,所以把签名流程做了个整理,以便将来复用。
一、常用签名流程
1、先将需要参与签名的键值对,根据键名称 ASCII 码排序
2、获取 value 值,拼接成一行
3、使用密钥,用 HmacSHA256 对拼接的字符串进行加密
4、加密后 的密文进行 base64 编码,生成加密的字符串
package main
import (
"crypto/hmac"
"crypto/sha256"
"encoding/base64"
"fmt"
"reflect"
"sort"
)
type SignTool struct {
SecretKey string
}
func NewSignTool(secret string) *SignTool {
return &SignTool{
SecretKey: secret,
}
}
func (s *SignTool) Sign(obj interface{}) string {
signmap := map[string]interface{}{}
valueOfObj := reflect.ValueOf(obj)
for i := 0; i < valueOfObj.NumField(); i++ {
signmap[valueOfObj.Type().Field(i).Name] = valueOfObj.Field(i)
}
//进行键排序
keys := make([]string, len(signmap))
j := 0
for k := range signmap {
keys[j] = k
j++
}
sort.Strings(keys)
//获取 value 值,拼接成一行
valueStr := ""
for _, k := range keys {
if v, ok := signmap[k]; ok {
valueStr = fmt.Sprintf("%s%v", valueStr, v)
}
}
//把 secretAccessKey 做为 key,用 HmacSHA256 对拼接的字符串
//加密后 的密文进行 base64 编码,生成加密的字符串
return hmacSha256(valueStr, s.SecretKey)
}
func hmacSha256(msg, pwd string) string {
h := hmac.New(sha256.New, []byte(pwd))
h.Write([]byte(msg))
return base64.StdEncoding.EncodeToString(h.Sum(nil))
}
// 测试签名的结构体
type Book struct {
Name string `json:"name"`
Price float32 `json:"price"`
Number int `json:"number"`
}
// 测试签名
func main() {
signTool := NewSignTool("abc")
book := Book{
Name: "我和我的祖国",
Price: 100.00,
Number: 20,
}
sign := signTool.Sign(book)
fmt.Println("签名结果: ", sign)
}