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) }