附近小店
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

155 lines
4.0 KiB

  1. package weapp
  2. import (
  3. "encoding/base64"
  4. "encoding/json"
  5. "errors"
  6. )
  7. // DecryptUserData 解密用户数据
  8. func DecryptUserData(ssk, ciphertext, iv string) ([]byte, error) {
  9. key, err := base64.StdEncoding.DecodeString(ssk)
  10. if err != nil {
  11. return nil, err
  12. }
  13. cipher, err := base64.StdEncoding.DecodeString(ciphertext)
  14. if err != nil {
  15. return nil, err
  16. }
  17. rawIV, err := base64.StdEncoding.DecodeString(iv)
  18. if err != nil {
  19. return nil, err
  20. }
  21. return cbcDecrypt(key, cipher, rawIV)
  22. }
  23. type watermark struct {
  24. AppID string `json:"appid"`
  25. Timestamp int64 `json:"timestamp"`
  26. }
  27. // Mobile 解密后的用户手机号码信息
  28. type Mobile struct {
  29. PhoneNumber string `json:"phoneNumber"`
  30. PurePhoneNumber string `json:"purePhoneNumber"`
  31. CountryCode string `json:"countryCode"`
  32. Watermark watermark `json:"watermark"`
  33. }
  34. // DecryptMobile 解密手机号码
  35. //
  36. // sessionKey 通过 Login 向微信服务端请求得到的 session_key
  37. // encryptedData 小程序通过 api 得到的加密数据(encryptedData)
  38. // iv 小程序通过 api 得到的初始向量(iv)
  39. func DecryptMobile(sessionKey, encryptedData, iv string) (*Mobile, error) {
  40. raw, err := DecryptUserData(sessionKey, encryptedData, iv)
  41. if err != nil {
  42. return nil, err
  43. }
  44. mobile := new(Mobile)
  45. if err := json.Unmarshal(raw, mobile); err != nil {
  46. return nil, err
  47. }
  48. return mobile, nil
  49. }
  50. // ShareInfo 解密后的分享信息
  51. type ShareInfo struct {
  52. GID string `json:"openGId"`
  53. }
  54. // DecryptShareInfo 解密转发信息的加密数据
  55. //
  56. // sessionKey 通过 Login 向微信服务端请求得到的 session_key
  57. // encryptedData 小程序通过 api 得到的加密数据(encryptedData)
  58. // iv 小程序通过 api 得到的初始向量(iv)
  59. //
  60. // gid 小程序唯一群号
  61. func DecryptShareInfo(sessionKey, encryptedData, iv string) (*ShareInfo, error) {
  62. raw, err := DecryptUserData(sessionKey, encryptedData, iv)
  63. if err != nil {
  64. return nil, err
  65. }
  66. info := new(ShareInfo)
  67. if err = json.Unmarshal(raw, info); err != nil {
  68. return nil, err
  69. }
  70. return info, nil
  71. }
  72. // UserInfo 解密后的用户信息
  73. type UserInfo struct {
  74. OpenID string `json:"openId"`
  75. Nickname string `json:"nickName"`
  76. Gender int `json:"gender"`
  77. Province string `json:"province"`
  78. Language string `json:"language"`
  79. Country string `json:"country"`
  80. City string `json:"city"`
  81. Avatar string `json:"avatarUrl"`
  82. UnionID string `json:"unionId"`
  83. Watermark watermark `json:"watermark"`
  84. }
  85. // DecryptUserInfo 解密用户信息
  86. //
  87. // sessionKey 微信 session_key
  88. // rawData 不包括敏感信息的原始数据字符串,用于计算签名。
  89. // encryptedData 包括敏感数据在内的完整用户信息的加密数据
  90. // signature 使用 sha1( rawData + session_key ) 得到字符串,用于校验用户信息
  91. // iv 加密算法的初始向量
  92. func DecryptUserInfo(sessionKey, rawData, encryptedData, signature, iv string) (*UserInfo, error) {
  93. if ok := validateUserInfo(signature, rawData, sessionKey); !ok {
  94. return nil, errors.New("failed to validate signature")
  95. }
  96. raw, err := DecryptUserData(sessionKey, encryptedData, iv)
  97. if err != nil {
  98. return nil, err
  99. }
  100. info := new(UserInfo)
  101. if err := json.Unmarshal(raw, info); err != nil {
  102. return nil, err
  103. }
  104. return info, nil
  105. }
  106. // RunData 解密后的最近30天微信运动步数
  107. type RunData struct {
  108. StepInfoList []SetpInfo `json:"stepInfoList"`
  109. }
  110. // SetpInfo 运动步数
  111. type SetpInfo struct {
  112. Step int `json:"step"`
  113. Timestamp int64 `json:"timestamp"`
  114. }
  115. // DecryptRunData 解密微信运动的加密数据
  116. //
  117. // sessionKey 通过 Login 向微信服务端请求得到的 session_key
  118. // encryptedData 小程序通过 api 得到的加密数据(encryptedData)
  119. // iv 小程序通过 api 得到的初始向量(iv)
  120. func DecryptRunData(sessionKey, encryptedData, iv string) (*RunData, error) {
  121. raw, err := DecryptUserData(sessionKey, encryptedData, iv)
  122. if err != nil {
  123. return nil, err
  124. }
  125. info := new(RunData)
  126. if err := json.Unmarshal(raw, info); err != nil {
  127. return nil, err
  128. }
  129. return info, nil
  130. }