|
- package zhios_pay_utils
-
- import (
- "crypto"
- "crypto/rand"
- "crypto/rsa"
- "crypto/sha1"
- "crypto/x509"
- "encoding/base64"
- "encoding/pem"
- "errors"
- "fmt"
- "golang.org/x/crypto/ssh"
- "sort"
- "strings"
- )
-
- func GetSign(privateKeyStr, data string) (string, error) {
- privateKey, err := ssh.ParseRawPrivateKey([]byte(privateKeyStr))
- if err != nil {
- return "", err
- }
- 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
- }
-
- func GetSignV2(privateKeyStr, data string, hash crypto.Hash) (string, error) {
- privateKey, err := ssh.ParseRawPrivateKey([]byte(privateKeyStr))
- if err != nil {
- return "", err
- }
- h := crypto.Hash.New(hash)
- h.Write([]byte(data))
- hashed := h.Sum(nil)
- sign, err := rsa.SignPKCS1v15(rand.Reader, privateKey.(*rsa.PrivateKey), hash, hashed)
- if err != nil {
- return "", nil
- }
- return base64.StdEncoding.EncodeToString(sign), nil
- }
-
- // RSA2公钥验证签名
- func Rsa2PubCheckSign(signContent, sign, publicKey string, hash crypto.Hash) bool {
- hashed := sha1.Sum([]byte(signContent))
- pubKey, err := ParsePublicKey(publicKey)
- if err != nil {
- return false
- }
- sig, _ := base64.StdEncoding.DecodeString(sign)
- err = rsa.VerifyPKCS1v15(pubKey, hash, hashed[:], sig)
- if err != nil {
- return false
- }
- return true
- }
-
- // 解析公钥
- func ParsePublicKey(publicKey string) (*rsa.PublicKey, error) {
- block, _ := pem.Decode([]byte(publicKey))
- if block == nil {
- return nil, errors.New("公钥信息错误!")
- }
- pubKey, err := x509.ParsePKIXPublicKey(block.Bytes)
- if err != nil {
- return nil, err
- }
- return pubKey.(*rsa.PublicKey), 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)
- }
|