|
|
- package helper
-
- import (
- "bytes"
- "encoding/base64"
- "encoding/hex"
- "errors"
- "git.tetele.net/tgo/crypter"
- "github.com/ZZMarquis/gm/sm2"
- "github.com/ZZMarquis/gm/sm3"
- jsoniter "github.com/json-iterator/go"
- "io/ioutil"
- "log"
- "math/big"
- "net/http"
- "reflect"
- "sort"
- "strings"
- "time"
- )
-
- var json = jsoniter.ConfigCompatibleWithStandardLibrary
-
- // 合并map数据
- func MergeMapData(x, y map[string]interface{}) map[string]interface{} {
-
- n := make(map[string]interface{})
-
- for i, v := range x {
- for j, w := range y {
- if i == j {
- n[i] = w
-
- } else {
- if _, ok := n[i]; !ok {
- n[i] = v
- }
- if _, ok := n[j]; !ok {
- n[j] = w
- }
- }
- }
- }
-
- return n
- }
-
- // 针对传参为json或者数组类型的字段,进行字符串排序
- func HttpBuildSort(data map[string]interface{}) string {
- keySlice := []string{}
-
- for k, _ := range data {
- keySlice = append(keySlice, k)
- }
- // 排序字符串
- sort.Strings(keySlice)
-
- res := make(map[string]interface{}, 0)
-
- for _, value := range keySlice {
- data_val := ToStr(data[value])
-
- if value != "" && data_val != "" {
- res[value] = data_val
- }
- }
-
- res_byte, _ := json.Marshal(res)
-
- return string(res_byte)
- }
-
- // body参数处理
- func FormatBodyData(body map[string]interface{}) map[string]interface{} {
- data := map[string]interface{}{}
-
- if len(body) > 0 {
- for k, v := range body {
- typeOfA := reflect.TypeOf(v)
-
- if typeOfA.Kind().String() == "map" {
- build_str_format, _ := InterfaceToMapInterface(v)
-
- if len(build_str_format) < 1 {
- continue
- }
- // json键值对处理
- data[k] = HttpBuildSort(build_str_format)
- // log.Println("排序后的数据: ", data[k])
- } else if typeOfA.Kind().String() == "slice" {
- val_slice := []interface{}{}
- // json键值对处理
- for _, val_inter := range v.([]interface{}) {
- val_map, _ := InterfaceToMapInterface(val_inter)
- each_val := HttpBuildSort(val_map)
- val_slice = append(val_slice, each_val)
- }
-
- if len(val_slice) < 1 {
- continue
- }
-
- data[k] = val_slice
- // log.Println("排序后的数据: ", data[k])
- } else {
- data[k] = v
- }
- }
- }
-
- return data
- }
-
- // 字符串排序拼接
- func CmbHttpBuildQuery(data map[string]interface{}, filter_sign bool) string {
- keySlice := []string{}
- // 剔除sign字段
- for k, _ := range data {
- if filter_sign && k == "sign" {
- continue
- }
- keySlice = append(keySlice, k)
- }
- // 排序字符串
- sort.Strings(keySlice)
-
- var query string
-
- for _, value := range keySlice {
- if value != "" && data[value] != "" {
- query += StringJoin(value, "=", ToStr(data[value]), "&")
- }
- }
-
- build_str := strings.Trim(query, "&")
-
- log.Println("拼接后的数据: ", build_str)
- return build_str
- }
-
- // 生成签名sign--聚合支付
- func SetSign(data map[string]interface{}, privateKey string) string {
- log.Println("招行加签start")
- build_str := CmbHttpBuildQuery(data, true)
-
- priv := new(sm2.PrivateKey)
- priv.Curve = sm2.GetSm2P256V1()
- dBytes, _ := hex.DecodeString(privateKey)
- priv.D = new(big.Int).SetBytes(dBytes)
-
- signature, err := sm2.Sign(priv, []byte("1234567812345678"), []byte(build_str))
-
- if err != nil {
- log.Println("国密加密异常", err)
- return ""
- }
-
- sign := base64.StdEncoding.EncodeToString(signature)
-
- log.Println("加密后sign值: ", sign)
- log.Println("招行加签end")
- return sign
- }
-
- // 创建请求头信息--聚合支付
- func HeaderInfo(appid, secret, sign string) map[string]string {
- if appid == "" || secret == "" || sign == "" {
- return map[string]string{}
- }
-
- headerData := map[string]string{}
-
- headerData["appid"] = appid
- headerData["sign"] = sign
- headerData["secret"] = secret
- headerData["timestamp"] = ToStr(time.Now().Unix())
-
- build_str := CmbHttpBuildQuery(MapStringToInterface(headerData), false)
-
- headerData["apisign"] = crypter.Md5Str(build_str)
-
- delete(headerData, "sign")
- delete(headerData, "secret")
-
- log.Println("header信息", headerData)
-
- return headerData
- }
-
- // 接口验签--各客户端请求我们接口验签
- func CheckSign(appid, app_secret, timeStamp, nonce, sign string, body map[string]interface{}) error {
- log.Println("请求验签start")
-
- /*time_now := time.Now().Unix()
-
- if time_now-ToInt64(timeStamp) > 10 {
- return errors.New("请求时间超出范围,拒绝访问")
- }*/
-
- sign_info := map[string]interface{}{
- "appid": appid,
- "timestamp": timeStamp,
- "nonce": nonce,
- }
-
- if len(body) > 0 {
- body_format := FormatBodyDataNoList(body)
- sign_info = MergeMapData(sign_info, body_format)
- }
-
- str := CmbHttpBuildQuery(sign_info, false) + "&" + app_secret
- log.Println("加密前数据: ", str)
- sign_str := crypter.Md5Str(str)
- log.Println("加密后数据: ", sign_str)
-
- if sign_str != sign {
- return errors.New("签名不正确")
- }
-
- log.Println("请求验签end")
-
- return nil
- }
-
- // post 请求
- func PostJsonData(url string, param interface{}, headerinfo map[string]string) ([]byte, error) {
- httpClient := &http.Client{}
- params, err := json.Marshal(param)
-
- if err != nil {
- return []byte(""), err
- }
-
- log.Println(bytes.NewBuffer(params))
-
- req, err := http.NewRequest("POST", url, bytes.NewBuffer(params))
- if err != nil {
- return []byte(""), err
- }
-
- req.Header.Set("Content-Type", "application/json")
-
- if len(headerinfo) > 0 {
- for k, v := range headerinfo {
- req.Header[k] = []string{v}
- }
- }
-
- resp, err := httpClient.Do(req)
- if err != nil {
- return []byte(""), err
- }
-
- defer resp.Body.Close()
- body, err := ioutil.ReadAll(resp.Body)
- if err != nil {
- return []byte(""), err
- }
-
- return body, nil
- }
-
- func SetSignsm3(data map[string]interface{}) string {
- build_str := HttpBuildjson(data, false)
- h := sm3.New()
- h.Write([]byte(build_str))
- sum := h.Sum(nil)
- sign := hex.EncodeToString(sum)
- return sign
- }
-
- func CashierHeaderInfoCompany(appid, secret, sign, private_key string) map[string]string {
- if appid == "" || secret == "" || sign == "" || private_key == "" {
- return map[string]string{}
- }
-
- headerData := map[string]string{}
-
- headerData["appid"] = appid
- headerData["sign"] = sign
- headerData["secret"] = secret
- headerData["timestamp"] = ToStr(time.Now().Unix())
- headerData["apisign"] = SetSignhex(headerData, private_key)
- headerData["verify"] = "SM3withSM2"
- delete(headerData, "secret")
- return headerData
- }
-
- // 生成签名sign
- func SetSignhex(data map[string]string, privateKey string) string {
- build_str := CmbHttpBuildQuery(MapStringToInterface(data), false)
- priv := new(sm2.PrivateKey)
- priv.Curve = sm2.GetSm2P256V1()
- dBytes, _ := hex.DecodeString(privateKey)
- priv.D = new(big.Int).SetBytes(dBytes)
- sign, _ := sm2.Sign(priv, []byte("1234567812345678"), []byte(build_str))
- sign = SM2Asn1ToRaw(sign)
- return hex.EncodeToString(sign)
- }
- func SM2Asn1ToRaw(data []byte) []byte {
- i := 3
- ret := []byte{}
- if data[i] == 32 {
- i = i + 1
- } else if data[i] == 33 {
- i = i + 2
- }
- for k := 0; k < 32; k++ {
- ret = append(ret, data[i+k])
- }
- i = i + 32
- i = i + 1
- if data[i] == 32 {
- i = i + 1
- } else if data[i] == 33 {
- i = i + 2
- }
- for k := 0; k < 32; k++ {
- ret = append(ret, data[i+k])
- }
- return ret
- }
-
- // 字符串排序拼接
- func HttpBuildjson(data map[string]interface{}, filter_sign bool) string {
- keySlice := []string{}
- res := map[string]interface{}{}
- // 剔除sign字段
- for k, _ := range data {
- if filter_sign && k == "sign" {
- continue
- }
- keySlice = append(keySlice, k)
- }
- // 排序字符串
- sort.Strings(keySlice)
- for _, value := range keySlice {
- if value != "" && data[value] != "" {
- res[value] = data[value]
- }
- }
- ss, _ := json.Marshal(res)
- log.Println("拼接后的数据: ", string(ss))
- return string(ss)
- }
-
- // body参数处理
- func FormatBodyDataNoList(body map[string]interface{}) map[string]interface{} {
- data := map[string]interface{}{}
-
- if len(body) > 0 {
- for k, v := range body {
- typeOfA := reflect.TypeOf(v)
-
- if typeOfA.Kind().String() == "map" || typeOfA.Kind().String() == "slice" {
- continue
- } else {
- if typeOfA.Kind().String() == "string" {
- if ToStr(v) != "" {
- data[k] = v
- }
- }
- }
- }
- }
-
- return data
- }
-
- // 聚合支付异步回调验签
- func JhNotifyCheckSign(sign, public_key string, data map[string]string) bool {
- build_sort_str := CmbHttpBuildQuery(MapStringToInterface(data), true)
- pub_x := ""
- pub_y := ""
- // 私钥截取
- if len(public_key) == 128 {
- pub_x = public_key[:64]
- pub_y = public_key[64:]
- } else if len(public_key) == 130 && (public_key[:2] == "04") {
- public_key = public_key[2:]
- pub_x = public_key[:64]
- pub_y = public_key[64:]
- } else {
- log.Println("异步验签公钥出错", public_key)
- return false
- }
-
- sign_b64, _ := base64.StdEncoding.DecodeString(sign)
- pub := new(sm2.PublicKey)
- pub.Curve = sm2.GetSm2P256V1()
- xBytes, _ := hex.DecodeString(pub_x)
- yBytes, _ := hex.DecodeString(pub_y)
- pub.X = new(big.Int).SetBytes(xBytes)
- pub.Y = new(big.Int).SetBytes(yBytes)
- result := sm2.Verify(pub, []byte("1234567812345678"), []byte(build_sort_str), sign_b64)
-
- if !result {
- return false
- }
-
- return true
- }
|