1
0
mirror of https://github.com/silenceper/wechat.git synced 2026-02-04 12:52:27 +08:00

fix some bugs (#277)

* fix payRequset xml marshal: root element should be xml

* support HMAC-SHA256 for unifiedorder api

* support HMAC-SHA256 for PaidVerifySign

* fix SignType is nil

* fix code style

* constantize SignType

* add comments

* fix code style
This commit is contained in:
huang wei
2020-06-14 23:23:58 +08:00
committed by GitHub
parent fe31f04640
commit c14c020a3c
6 changed files with 97 additions and 95 deletions

View File

@@ -1,14 +1,23 @@
package util
import (
"bufio"
"bytes"
"crypto/aes"
"crypto/cipher"
"crypto/hmac"
"crypto/md5"
"crypto/sha256"
"encoding/base64"
"encoding/hex"
"errors"
"fmt"
"hash"
"strings"
)
// 微信签名算法方式
const (
SignTypeMD5 = `MD5`
SignTypeHMACSHA256 = `HMAC-SHA256`
)
//EncryptMsg 加密消息
@@ -186,14 +195,35 @@ func decodeNetworkByteOrder(orderBytes []byte) (n uint32) {
uint32(orderBytes[3])
}
// MD5Sum 计算 32 位长度的 MD5 sum
func MD5Sum(txt string) (sum string) {
h := md5.New()
buf := bufio.NewWriterSize(h, 128)
buf.WriteString(txt)
buf.Flush()
sign := make([]byte, hex.EncodedLen(h.Size()))
hex.Encode(sign, h.Sum(nil))
sum = string(bytes.ToUpper(sign))
return
// CalculateSign 计算签名
func CalculateSign(content, signType, key string) (string, error) {
var h hash.Hash
if signType == SignTypeMD5 {
h = md5.New()
} else {
h = hmac.New(sha256.New, []byte(key))
}
if _, err := h.Write([]byte(content)); err != nil {
return ``, err
}
return strings.ToUpper(hex.EncodeToString(h.Sum(nil))), nil
}
// ParamSign 计算所传参数的签名
func ParamSign(p map[string]string, key string) (string, error) {
bizKey := "&key=" + key
str := OrderParam(p, bizKey)
var signType string
switch p["sign_type"] {
case SignTypeMD5, SignTypeHMACSHA256:
signType = p["sign_type"]
case ``:
signType = SignTypeMD5
default:
return ``, errors.New(`invalid sign_type`)
}
return CalculateSign(str, signType, key)
}

View File

@@ -3,65 +3,31 @@ package util
import (
"bytes"
"sort"
"strconv"
)
// OrderParam order params
func OrderParam(source interface{}, bizKey string) (returnStr string) {
switch v := source.(type) {
case map[string]string:
keys := make([]string, 0, len(v))
for k := range v {
if k == "sign" {
continue
}
keys = append(keys, k)
func OrderParam(p map[string]string, bizKey string) (returnStr string) {
keys := make([]string, 0, len(p))
for k := range p {
if k == "sign" {
continue
}
sort.Strings(keys)
var buf bytes.Buffer
for _, k := range keys {
if v[k] == "" {
continue
}
if buf.Len() > 0 {
buf.WriteByte('&')
}
buf.WriteString(k)
buf.WriteByte('=')
buf.WriteString(v[k])
}
buf.WriteString(bizKey)
returnStr = buf.String()
case map[string]interface{}:
keys := make([]string, 0, len(v))
for k := range v {
if k == "sign" {
continue
}
keys = append(keys, k)
}
sort.Strings(keys)
var buf bytes.Buffer
for _, k := range keys {
if v[k] == "" {
continue
}
if buf.Len() > 0 {
buf.WriteByte('&')
}
buf.WriteString(k)
buf.WriteByte('=')
switch vv := v[k].(type) {
case string:
buf.WriteString(vv)
case int:
buf.WriteString(strconv.FormatInt(int64(vv), 10))
default:
panic("params type not supported")
}
}
buf.WriteString(bizKey)
returnStr = buf.String()
keys = append(keys, k)
}
sort.Strings(keys)
var buf bytes.Buffer
for _, k := range keys {
if p[k] == "" {
continue
}
if buf.Len() > 0 {
buf.WriteByte('&')
}
buf.WriteString(k)
buf.WriteByte('=')
buf.WriteString(p[k])
}
buf.WriteString(bizKey)
returnStr = buf.String()
return
}