decrypt.go 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293
  1. package miniprogram
  2. import (
  3. "crypto/aes"
  4. "crypto/cipher"
  5. "encoding/base64"
  6. "encoding/json"
  7. "errors"
  8. )
  9. var (
  10. // ErrAppIDNotMatch appid不匹配
  11. ErrAppIDNotMatch = errors.New("app id not match")
  12. // ErrInvalidBlockSize block size不合法
  13. ErrInvalidBlockSize = errors.New("invalid block size")
  14. // ErrInvalidPKCS7Data PKCS7数据不合法
  15. ErrInvalidPKCS7Data = errors.New("invalid PKCS7 data")
  16. // ErrInvalidPKCS7Padding 输入padding失败
  17. ErrInvalidPKCS7Padding = errors.New("invalid padding on input")
  18. )
  19. // UserInfo 用户信息
  20. type UserInfo struct {
  21. OpenID string `json:"openId"`
  22. UnionID string `json:"unionId"`
  23. NickName string `json:"nickName"`
  24. Gender int `json:"gender"`
  25. City string `json:"city"`
  26. Province string `json:"province"`
  27. Country string `json:"country"`
  28. AvatarURL string `json:"avatarUrl"`
  29. Language string `json:"language"`
  30. Watermark struct {
  31. Timestamp int64 `json:"timestamp"`
  32. AppID string `json:"appid"`
  33. } `json:"watermark"`
  34. }
  35. // pkcs7Unpad returns slice of the original data without padding
  36. func pkcs7Unpad(data []byte, blockSize int) ([]byte, error) {
  37. if blockSize <= 0 {
  38. return nil, ErrInvalidBlockSize
  39. }
  40. if len(data)%blockSize != 0 || len(data) == 0 {
  41. return nil, ErrInvalidPKCS7Data
  42. }
  43. c := data[len(data)-1]
  44. n := int(c)
  45. if n == 0 || n > len(data) {
  46. return nil, ErrInvalidPKCS7Padding
  47. }
  48. for i := 0; i < n; i++ {
  49. if data[len(data)-n+i] != c {
  50. return nil, ErrInvalidPKCS7Padding
  51. }
  52. }
  53. return data[:len(data)-n], nil
  54. }
  55. // Decrypt 解密数据
  56. func (wxa *MiniProgram) Decrypt(sessionKey, encryptedData, iv string) (*UserInfo, error) {
  57. aesKey, err := base64.StdEncoding.DecodeString(sessionKey)
  58. if err != nil {
  59. return nil, err
  60. }
  61. cipherText, err := base64.StdEncoding.DecodeString(encryptedData)
  62. if err != nil {
  63. return nil, err
  64. }
  65. ivBytes, err := base64.StdEncoding.DecodeString(iv)
  66. if err != nil {
  67. return nil, err
  68. }
  69. block, err := aes.NewCipher(aesKey)
  70. if err != nil {
  71. return nil, err
  72. }
  73. mode := cipher.NewCBCDecrypter(block, ivBytes)
  74. mode.CryptBlocks(cipherText, cipherText)
  75. cipherText, err = pkcs7Unpad(cipherText, block.BlockSize())
  76. if err != nil {
  77. return nil, err
  78. }
  79. var userInfo UserInfo
  80. err = json.Unmarshal(cipherText, &userInfo)
  81. if err != nil {
  82. return nil, err
  83. }
  84. if userInfo.Watermark.AppID != wxa.AppID {
  85. return nil, ErrAppIDNotMatch
  86. }
  87. return &userInfo, nil
  88. }