verify.go 1.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104
  1. package wx
  2. import (
  3. "crypto/md5"
  4. "encoding/hex"
  5. "encoding/xml"
  6. "errors"
  7. "io"
  8. "net/url"
  9. "sort"
  10. "strings"
  11. )
  12. type XMLMap url.Values
  13. type xmlMapEntry struct {
  14. XMLName xml.Name
  15. Value string `xml:",chardata"`
  16. }
  17. func (m XMLMap) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
  18. for {
  19. var e xmlMapEntry
  20. err := d.Decode(&e)
  21. if err == io.EOF {
  22. break
  23. } else if err != nil {
  24. return err
  25. }
  26. (m)[e.XMLName.Local] = []string{e.Value}
  27. }
  28. return nil
  29. }
  30. func (v XMLMap) Get(key string) string {
  31. if v == nil {
  32. return ""
  33. }
  34. vs := v[key]
  35. if len(vs) == 0 {
  36. return ""
  37. }
  38. return vs[0]
  39. }
  40. func (v XMLMap) Set(key, value string) {
  41. v[key] = []string{value}
  42. }
  43. func (v XMLMap) Add(key, value string) {
  44. v[key] = append(v[key], value)
  45. }
  46. func (v XMLMap) Del(key string) {
  47. delete(v, key)
  48. }
  49. func VerifyResponseData(data []byte, key string) (ok bool, err error) {
  50. var param = make(XMLMap)
  51. err = xml.Unmarshal(data, &param)
  52. if err != nil {
  53. return false, err
  54. }
  55. return VerifyResponseValues(url.Values(param), key)
  56. }
  57. func VerifyResponseValues(param url.Values, key string) (bool, error) {
  58. // 验证签名
  59. var sign = param.Get("sign")
  60. delete(param, "sign")
  61. if sign == "" {
  62. return false, errors.New("签名验证失败")
  63. }
  64. var sign2 = SignMD5(param, key)
  65. if sign == sign2 {
  66. return true, nil
  67. }
  68. return false, errors.New("签名验证失败")
  69. }
  70. func SignMD5(param url.Values, key string) (sign string) {
  71. var pList = make([]string, 0, 0)
  72. for key := range param {
  73. var value = param.Get(key)
  74. if len(value) > 0 {
  75. pList = append(pList, key+"="+value)
  76. }
  77. }
  78. sort.Strings(pList)
  79. if key != "" {
  80. pList = append(pList, "key="+key)
  81. }
  82. var src = strings.Join(pList, "&")
  83. md5Ctx := md5.New()
  84. md5Ctx.Write([]byte(src))
  85. cipherStr := md5Ctx.Sum(nil)
  86. sign = strings.ToUpper(hex.EncodeToString(cipherStr))
  87. return sign
  88. }