wxbizdatacrypt.go 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596
  1. package wxbizdatacrypt
  2. import (
  3. "crypto/aes"
  4. "crypto/cipher"
  5. "encoding/base64"
  6. "encoding/json"
  7. "errors"
  8. "fmt"
  9. "strings"
  10. )
  11. var errorCode = map[string]int{
  12. "IllegalAesKey" : -41001,
  13. "IllegalIv" : -41002,
  14. "IllegalBuffer" : -41003,
  15. "DecodeBase64Error" : -41004,
  16. }
  17. // WxBizDataCrypt represents an active WxBizDataCrypt object
  18. type WxBizDataCrypt struct {
  19. AppID string
  20. SessionKey string
  21. }
  22. type showError struct {
  23. errorCode int
  24. errorMsg error
  25. }
  26. func (e showError) Error() string {
  27. return fmt.Sprintf("{code: %v, error: \"%v\"}", e.errorCode, e.errorMsg)
  28. }
  29. // Decrypt Weixin APP's AES Data
  30. // If isJSON is true, Decrypt return JSON type.
  31. // If isJSON is false, Decrypt return map type.
  32. func (wxCrypt *WxBizDataCrypt) Decrypt(encryptedData string, iv string, isJSON bool) (interface{}, error) {
  33. if len(wxCrypt.SessionKey) != 24 {
  34. return nil, showError{errorCode["IllegalAesKey"], errors.New("sessionKey length is error")}
  35. }
  36. aesKey, err := base64.StdEncoding.DecodeString(wxCrypt.SessionKey)
  37. if err != nil {
  38. return nil, showError{errorCode["DecodeBase64Error"], err}
  39. }
  40. if len(iv) != 24 {
  41. return nil, showError{errorCode["IllegalIv"], errors.New("iv length is error")}
  42. }
  43. aesIV, err := base64.StdEncoding.DecodeString(iv)
  44. if err != nil {
  45. return nil, showError{errorCode["DecodeBase64Error"], err}
  46. }
  47. aesCipherText, err := base64.StdEncoding.DecodeString(encryptedData)
  48. if err != nil {
  49. return nil, showError{errorCode["DecodeBase64Error"], err}
  50. }
  51. aesPlantText := make([]byte, len(aesCipherText))
  52. aesBlock, err := aes.NewCipher(aesKey)
  53. if err != nil {
  54. return nil, showError{errorCode["IllegalBuffer"], err}
  55. }
  56. mode := cipher.NewCBCDecrypter(aesBlock, aesIV)
  57. mode.CryptBlocks(aesPlantText, aesCipherText)
  58. aesPlantText = PKCS7UnPadding(aesPlantText)
  59. var decrypted map[string]interface{}
  60. aesPlantText = []byte(strings.Replace(string(aesPlantText), "\a", "", -1))
  61. err = json.Unmarshal([]byte(aesPlantText), &decrypted)
  62. if err != nil {
  63. return nil, showError{errorCode["IllegalBuffer"], err}
  64. }
  65. if decrypted["watermark"].(map[string]interface{})["appid"] != wxCrypt.AppID {
  66. return nil, showError{errorCode["IllegalBuffer"], errors.New("appId is not match")}
  67. }
  68. if isJSON == true {
  69. return string(aesPlantText), nil
  70. }
  71. return decrypted, nil
  72. }
  73. // PKCS7UnPadding return unpadding []Byte plantText
  74. func PKCS7UnPadding(plantText []byte) []byte {
  75. length := len(plantText)
  76. unPadding := int(plantText[length-1])
  77. if unPadding < 1 || unPadding > 32 {
  78. unPadding = 0
  79. }
  80. return plantText[:(length - unPadding)]
  81. }