|
|
@@ -0,0 +1,104 @@
|
|
|
+package wx
|
|
|
+
|
|
|
+import (
|
|
|
+ "crypto/md5"
|
|
|
+ "encoding/hex"
|
|
|
+ "encoding/xml"
|
|
|
+ "errors"
|
|
|
+ "io"
|
|
|
+ "net/url"
|
|
|
+ "sort"
|
|
|
+ "strings"
|
|
|
+)
|
|
|
+
|
|
|
+type XMLMap url.Values
|
|
|
+
|
|
|
+type xmlMapEntry struct {
|
|
|
+ XMLName xml.Name
|
|
|
+ Value string `xml:",chardata"`
|
|
|
+}
|
|
|
+
|
|
|
+func (m XMLMap) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
|
|
|
+ for {
|
|
|
+ var e xmlMapEntry
|
|
|
+ err := d.Decode(&e)
|
|
|
+ if err == io.EOF {
|
|
|
+ break
|
|
|
+ } else if err != nil {
|
|
|
+ return err
|
|
|
+ }
|
|
|
+ (m)[e.XMLName.Local] = []string{e.Value}
|
|
|
+ }
|
|
|
+ return nil
|
|
|
+}
|
|
|
+
|
|
|
+func (v XMLMap) Get(key string) string {
|
|
|
+ if v == nil {
|
|
|
+ return ""
|
|
|
+ }
|
|
|
+ vs := v[key]
|
|
|
+ if len(vs) == 0 {
|
|
|
+ return ""
|
|
|
+ }
|
|
|
+ return vs[0]
|
|
|
+}
|
|
|
+
|
|
|
+func (v XMLMap) Set(key, value string) {
|
|
|
+ v[key] = []string{value}
|
|
|
+}
|
|
|
+
|
|
|
+func (v XMLMap) Add(key, value string) {
|
|
|
+ v[key] = append(v[key], value)
|
|
|
+}
|
|
|
+
|
|
|
+func (v XMLMap) Del(key string) {
|
|
|
+ delete(v, key)
|
|
|
+}
|
|
|
+
|
|
|
+func VerifyResponseData(data []byte, key string) (ok bool, err error) {
|
|
|
+ var param = make(XMLMap)
|
|
|
+ err = xml.Unmarshal(data, ¶m)
|
|
|
+ if err != nil {
|
|
|
+ return false, err
|
|
|
+ }
|
|
|
+
|
|
|
+ return VerifyResponseValues(url.Values(param), key)
|
|
|
+}
|
|
|
+
|
|
|
+func VerifyResponseValues(param url.Values, key string) (bool, error) {
|
|
|
+ // 验证签名
|
|
|
+ var sign = param.Get("sign")
|
|
|
+ delete(param, "sign")
|
|
|
+ if sign == "" {
|
|
|
+ return false, errors.New("签名验证失败")
|
|
|
+ }
|
|
|
+
|
|
|
+ var sign2 = SignMD5(param, key)
|
|
|
+ if sign == sign2 {
|
|
|
+ return true, nil
|
|
|
+ }
|
|
|
+ return false, errors.New("签名验证失败")
|
|
|
+}
|
|
|
+
|
|
|
+func SignMD5(param url.Values, key string) (sign string) {
|
|
|
+ var pList = make([]string, 0, 0)
|
|
|
+ for key := range param {
|
|
|
+ var value = param.Get(key)
|
|
|
+ if len(value) > 0 {
|
|
|
+ pList = append(pList, key+"="+value)
|
|
|
+ }
|
|
|
+ }
|
|
|
+ sort.Strings(pList)
|
|
|
+ if key != "" {
|
|
|
+ pList = append(pList, "key="+key)
|
|
|
+ }
|
|
|
+
|
|
|
+ var src = strings.Join(pList, "&")
|
|
|
+ md5Ctx := md5.New()
|
|
|
+ md5Ctx.Write([]byte(src))
|
|
|
+ cipherStr := md5Ctx.Sum(nil)
|
|
|
+
|
|
|
+ sign = strings.ToUpper(hex.EncodeToString(cipherStr))
|
|
|
+ return sign
|
|
|
+}
|
|
|
+
|