diff --git a/lib/boc/api_macao.go b/lib/boc/api_macao.go new file mode 100644 index 0000000..9e24574 --- /dev/null +++ b/lib/boc/api_macao.go @@ -0,0 +1 @@ +package boc diff --git a/test/boc_pay_test.go b/test/boc_pay_test.go new file mode 100644 index 0000000..89d52d5 --- /dev/null +++ b/test/boc_pay_test.go @@ -0,0 +1,13 @@ +package test + +import ( + zhios_pay_utils "code.fnuoos.com/go_rely_warehouse/zyos_go_pay.git/utils" + "fmt" + "testing" +) + +func TestJoinStringsInASCII(t *testing.T) { + ascii := zhios_pay_utils.JoinStringsInASCII(map[string]string{"apam": "value1", "cpam": "value2", "Bpam": "value3"}, + "", "", false, false) + fmt.Println(ascii) +} diff --git a/utils/RsaSign.go b/utils/RsaSign.go new file mode 100644 index 0000000..2a2dffe --- /dev/null +++ b/utils/RsaSign.go @@ -0,0 +1,91 @@ +package zhios_pay_utils + +import ( + "crypto" + "crypto/rand" + "crypto/rsa" + "encoding/base64" + "fmt" + "golang.org/x/crypto/ssh" + "sort" + "strings" +) + +func GetSign(method, privateKeyStr string, param map[string]interface{}) (string, error) { + privateKey, err := ssh.ParseRawPrivateKey([]byte(privateKeyStr)) + if err != nil { + return "", err + } + keys := make([]string, 0, len(param)) + for k := range param { + keys = append(keys, k) + } + sort.Strings(keys) + data := "/api" + method + for _, v := range keys { + if strings.Contains(data, "?") == false { + data += "?" + v + "=" + param[v].(string) + } else { + data += "&" + v + "=" + param[v].(string) + } + } + fmt.Println(privateKey.(*rsa.PrivateKey)) + fmt.Println(data) + h := crypto.Hash.New(crypto.SHA256) + h.Write([]byte(data)) + hashed := h.Sum(nil) + sign, err := rsa.SignPKCS1v15(rand.Reader, privateKey.(*rsa.PrivateKey), crypto.SHA256, hashed) + if err != nil { + return "", nil + } + return base64.StdEncoding.EncodeToString(sign), nil +} + +//规则: +//◆ 参数名ASCII码从小到大排序(字典序); +//◆ 如果参数的值为空不参与签名; +//◆ 参数名区分大小写; +//◆ 接口請求成功時,需對返回參數使用平台提供的公鑰進行驗簽,传送的sign参数不参与签名,将生成的签名与该sign值作校验。 +// +// JoinStringsInASCII +// @Description: 按照规则,参数名ASCII码从小到大排序后拼接 +// @param data 待拼接的数据 +// @param sep 连接符 +// @param onlyValues 是否只包含参数值,true则不包含参数名,否则参数名和参数值均有 +// @param includeEmpty 是否包含空值,true则包含空值,否则不包含,注意此参数不影响参数名的存在 +// @param exceptKeys 被排除的参数名,不参与排序及拼接 +// @return string +// +func JoinStringsInASCII(data map[string]string, sep, KeyValueSep string, onlyValues, includeEmpty bool, exceptKeys ...string) string { + var list []string + var keyList []string + m := make(map[string]int) + if len(exceptKeys) > 0 { + for _, except := range exceptKeys { + m[except] = 1 + } + } + for k := range data { + if _, ok := m[k]; ok { + continue + } + value := data[k] + if !includeEmpty && value == "" { + continue + } + if onlyValues { + keyList = append(keyList, k) + } else { + list = append(list, fmt.Sprintf("%s%s%s", k, KeyValueSep, value)) + } + } + if onlyValues { + sort.Strings(keyList) + for _, v := range keyList { + list = append(list, data[v]) + } + } else { + sort.Strings(list) + } + return strings.Join(list, sep) +}