http.go 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232
  1. package asign
  2. import (
  3. "bytes"
  4. "crypto"
  5. "crypto/md5"
  6. "crypto/rand"
  7. "crypto/rsa"
  8. "crypto/sha1"
  9. "crypto/x509"
  10. "encoding/base64"
  11. "encoding/hex"
  12. "encoding/pem"
  13. "fmt"
  14. "io"
  15. "mime/multipart"
  16. "mtp2_if/config"
  17. "mtp2_if/logger"
  18. "net/http"
  19. "reflect"
  20. "sort"
  21. "strconv"
  22. "strings"
  23. "time"
  24. )
  25. // HttpPost
  26. //
  27. // 爱签HttpPost请求方法
  28. func HttpPost(apiUrl string, bizData map[string]interface{}) (rspBody []byte, err error) {
  29. appId := config.SerCfg.AsignCfg.AppId
  30. privateKey := fmt.Sprintf("-----BEGIN PRIVATE KEY-----\n%s\n-----END PRIVATE KEY-----", config.SerCfg.AsignCfg.PrivateKey)
  31. // fuck asign dev.
  32. timestamp := strconv.Itoa(int(time.Now().UnixMilli() + 10000*60))
  33. // 签名
  34. sortedData := sortMapByKey(bizData)
  35. signature, err := getSignature(sortedData, appId, timestamp, privateKey)
  36. if err != nil {
  37. logger.GetLogger().Errorf("[asign.HttpPost] 签名失败:" + err.Error())
  38. return
  39. }
  40. // 构建form-data请求参数
  41. var requestBody bytes.Buffer
  42. multipartWriter := multipart.NewWriter(&requestBody)
  43. multipartWriter.WriteField("appId", appId)
  44. multipartWriter.WriteField("timestamp", timestamp)
  45. multipartWriter.WriteField("bizData", sortedData)
  46. multipartWriter.Close()
  47. // 构建请求
  48. req, err := http.NewRequest("POST", apiUrl, &requestBody)
  49. // 设置请求头
  50. req.Header.Set("sign", signature)
  51. req.Header.Set("timestamp", timestamp)
  52. req.Header.Set("Content-Type", multipartWriter.FormDataContentType())
  53. // 调用接口
  54. client := &http.Client{}
  55. rsp, err := client.Do(req)
  56. if err != nil {
  57. logger.GetLogger().Errorf("[asign.HttpPost] 调用接口失败:" + err.Error())
  58. return
  59. }
  60. defer rsp.Body.Close()
  61. rspBody, err = io.ReadAll(rsp.Body)
  62. return
  63. }
  64. func HttpPost2(apiUrl string, bizData []map[string]interface{}) (rspBody []byte, err error) {
  65. appId := config.SerCfg.AsignCfg.AppId
  66. privateKey := fmt.Sprintf("-----BEGIN PRIVATE KEY-----\n%s\n-----END PRIVATE KEY-----", config.SerCfg.AsignCfg.PrivateKey)
  67. // fuck asign dev.
  68. timestamp := strconv.Itoa(int(time.Now().UnixMilli() + 10000*60))
  69. // 签名
  70. sortedData := "["
  71. for i, item := range bizData {
  72. if i > 0 {
  73. sortedData += ","
  74. }
  75. sortedData += sortMapByKey(item)
  76. }
  77. sortedData += "]"
  78. signature, err := getSignature(sortedData, appId, timestamp, privateKey)
  79. if err != nil {
  80. logger.GetLogger().Errorf("[asign.HttpPost] 签名失败:" + err.Error())
  81. return
  82. }
  83. // 构建form-data请求参数
  84. var requestBody bytes.Buffer
  85. multipartWriter := multipart.NewWriter(&requestBody)
  86. multipartWriter.WriteField("appId", appId)
  87. multipartWriter.WriteField("timestamp", timestamp)
  88. multipartWriter.WriteField("bizData", sortedData)
  89. multipartWriter.Close()
  90. // 构建请求
  91. req, err := http.NewRequest("POST", apiUrl, &requestBody)
  92. // 设置请求头
  93. req.Header.Set("sign", signature)
  94. req.Header.Set("timestamp", timestamp)
  95. req.Header.Set("Content-Type", multipartWriter.FormDataContentType())
  96. // 调用接口
  97. client := &http.Client{}
  98. rsp, err := client.Do(req)
  99. if err != nil {
  100. logger.GetLogger().Errorf("[asign.HttpPost] 调用接口失败:" + err.Error())
  101. return
  102. }
  103. defer rsp.Body.Close()
  104. rspBody, err = io.ReadAll(rsp.Body)
  105. return
  106. }
  107. // 签名规范:
  108. // 1、表单提交方式:form-data
  109. // 示例:1B2M2Y8AsgTpgAmY7PhCfg==
  110. // 2、请求头部参数
  111. // 参数1:sign(签名值,具体算法参考一下的前面算法)
  112. // 参数2:timestamp(时间戳,13位)
  113. // 3、请求体参数:
  114. // 参数1:appId(appId值,每个接入者唯一一个)
  115. // 参数2:timestamp(时间戳,13位,与上述一致)
  116. // 参数3:bizData(json字符串,举个例子,比方说要传合同编号如:{"contractNo":"0001"})
  117. // 4、签名算法:
  118. // 4.1、将上述3所属的bizData(json字符串),按照阿拉伯字母排序(如:{"ba":1,"ac":2}--->{"ac":2,"ba":1}),
  119. // 4.2、将4.1排序后的字符串,将【bizData+md5(bizData)+ appId + timestatmp】拼接后利用RSA非对称加密算法(SHA1withRSA),计算出最后的签名sign,对其base64编码,放入head的key(sign)中。
  120. //
  121. // String sign ;
  122. // String rsaSuffix = jsonStr + DigestUtils.md5Hex ( jsonStr ) + appId + timestatmp ;
  123. // byte [] bytes = RSAUtils.generateSHA1withRSASignature ( rsaSuffix, privateKey ) ;
  124. // try {
  125. // sign = Base64Utils.encode ( bytes ) ;
  126. // sign = sign.replaceAll ( " \r\n" , "" ) ;
  127. // } catch ( Exception e ) {
  128. // log.error( "sdk异常", e ) ;
  129. // return ApiRespBody.create ( ApiResponseInfo. _ERROR ) ;
  130. // }
  131. func getSignature(sortedData string, appId, timestamp, privateKey string) (signature string, err error) {
  132. pem10, _ := pem.Decode([]byte(privateKey))
  133. privateKey10I, _ := x509.ParsePKCS8PrivateKey(pem10.Bytes)
  134. privateKey10 := privateKey10I.(*rsa.PrivateKey)
  135. // md5(bizData)
  136. m := md5.New()
  137. m.Write([]byte(sortedData))
  138. bdMd5Hx := hex.EncodeToString(m.Sum(nil))
  139. // 待签内容
  140. message := sortedData + bdMd5Hx + appId + timestamp
  141. h := sha1.New()
  142. h.Write([]byte(message))
  143. sum := h.Sum(nil)
  144. // 使用私钥进行签名
  145. sign, err := rsa.SignPKCS1v15(rand.Reader, privateKey10, crypto.SHA1, sum)
  146. if err != nil {
  147. fmt.Println("Error signing:", err)
  148. return
  149. }
  150. // fmt.Println(signature)
  151. signature = base64.StdEncoding.EncodeToString(sign)
  152. signature = strings.ReplaceAll(signature, "\r\n", "")
  153. return
  154. }
  155. // sortMapByKey 按key排序map返回string
  156. func sortMapByKey(data map[string]interface{}) (sortedData string) {
  157. keys := make([]string, 0, len(data))
  158. for k := range data {
  159. keys = append(keys, k)
  160. }
  161. sort.Strings(keys)
  162. for i, k := range keys {
  163. if i > 0 {
  164. sortedData += ","
  165. }
  166. // 判断是否指针
  167. v := reflect.ValueOf(data[k])
  168. if v.Kind() == reflect.Ptr {
  169. switch data[k].(type) {
  170. case *string:
  171. sortedData += fmt.Sprintf(`"%s":"%s"`, k, *(data[k].(*string)))
  172. case *map[string]interface{}:
  173. sortedData += fmt.Sprintf(`"%s":%s`, k, sortMapByKey(*(data[k].(*map[string]interface{}))))
  174. case *[]interface{}:
  175. list := data[k].([]interface{})
  176. sortedData += fmt.Sprintf(`"%s":[`, k)
  177. for j, item := range list {
  178. if j > 0 {
  179. sortedData += ","
  180. }
  181. sortedData += sortMapByKey(item.(map[string]interface{}))
  182. }
  183. sortedData += "]"
  184. default:
  185. sortedData += fmt.Sprintf(`"%s":%v`, k, reflect.ValueOf(data[k]).Elem())
  186. }
  187. } else {
  188. switch data[k].(type) {
  189. case string:
  190. sortedData += fmt.Sprintf(`"%s":"%s"`, k, data[k].(string))
  191. case map[string]interface{}:
  192. sortedData += fmt.Sprintf(`"%s":%s`, k, sortMapByKey(data[k].(map[string]interface{})))
  193. case []interface{}:
  194. list := data[k].([]interface{})
  195. sortedData += fmt.Sprintf(`"%s":[`, k)
  196. for j, item := range list {
  197. if j > 0 {
  198. sortedData += ","
  199. }
  200. sortedData += sortMapByKey(item.(map[string]interface{}))
  201. }
  202. sortedData += "]"
  203. default:
  204. sortedData += fmt.Sprintf(`"%s":%v`, k, data[k])
  205. }
  206. }
  207. }
  208. return fmt.Sprintf("{%s}", sortedData)
  209. }