支付模块
Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.

125 lignes
3.3 KiB

  1. package zhios_pay_utils
  2. import (
  3. "crypto"
  4. "crypto/rand"
  5. "crypto/rsa"
  6. "crypto/sha1"
  7. "crypto/x509"
  8. "encoding/base64"
  9. "encoding/pem"
  10. "errors"
  11. "fmt"
  12. "golang.org/x/crypto/ssh"
  13. "sort"
  14. "strings"
  15. )
  16. func GetSign(privateKeyStr, data string) (string, error) {
  17. privateKey, err := ssh.ParseRawPrivateKey([]byte(privateKeyStr))
  18. if err != nil {
  19. return "", err
  20. }
  21. fmt.Println(privateKey.(*rsa.PrivateKey))
  22. fmt.Println(data)
  23. h := crypto.Hash.New(crypto.SHA256)
  24. h.Write([]byte(data))
  25. hashed := h.Sum(nil)
  26. sign, err := rsa.SignPKCS1v15(rand.Reader, privateKey.(*rsa.PrivateKey), crypto.SHA256, hashed)
  27. if err != nil {
  28. return "", nil
  29. }
  30. return base64.StdEncoding.EncodeToString(sign), nil
  31. }
  32. func GetSignV2(privateKeyStr, data string, hash crypto.Hash) (string, error) {
  33. privateKey, err := ssh.ParseRawPrivateKey([]byte(privateKeyStr))
  34. if err != nil {
  35. return "", err
  36. }
  37. h := crypto.Hash.New(hash)
  38. h.Write([]byte(data))
  39. hashed := h.Sum(nil)
  40. sign, err := rsa.SignPKCS1v15(rand.Reader, privateKey.(*rsa.PrivateKey), hash, hashed)
  41. if err != nil {
  42. return "", nil
  43. }
  44. return base64.StdEncoding.EncodeToString(sign), nil
  45. }
  46. // RSA2公钥验证签名
  47. func Rsa2PubCheckSign(signContent, sign, publicKey string, hash crypto.Hash) bool {
  48. hashed := sha1.Sum([]byte(signContent))
  49. pubKey, err := ParsePublicKey(publicKey)
  50. if err != nil {
  51. return false
  52. }
  53. sig, _ := base64.StdEncoding.DecodeString(sign)
  54. err = rsa.VerifyPKCS1v15(pubKey, hash, hashed[:], sig)
  55. if err != nil {
  56. return false
  57. }
  58. return true
  59. }
  60. // 解析公钥
  61. func ParsePublicKey(publicKey string) (*rsa.PublicKey, error) {
  62. block, _ := pem.Decode([]byte(publicKey))
  63. if block == nil {
  64. return nil, errors.New("公钥信息错误!")
  65. }
  66. pubKey, err := x509.ParsePKIXPublicKey(block.Bytes)
  67. if err != nil {
  68. return nil, err
  69. }
  70. return pubKey.(*rsa.PublicKey), nil
  71. }
  72. //◆ 参数名ASCII码从小到大排序(字典序);
  73. //◆ 如果参数的值为空不参与签名;
  74. //◆ 参数名区分大小写;
  75. //◆ 接口請求成功時,需對返回參數使用平台提供的公鑰進行驗簽,传送的sign参数不参与签名,将生成的签名与该sign值作校验。
  76. //
  77. // JoinStringsInASCII
  78. // @Description: 按照规则,参数名ASCII码从小到大排序后拼接
  79. // @param data 待拼接的数据
  80. // @param sep 连接符
  81. // @param onlyValues 是否只包含参数值,true则不包含参数名,否则参数名和参数值均有
  82. // @param includeEmpty 是否包含空值,true则包含空值,否则不包含,注意此参数不影响参数名的存在
  83. // @param exceptKeys 被排除的参数名,不参与排序及拼接
  84. // @return string
  85. //
  86. func JoinStringsInASCII(data map[string]string, sep, KeyValueSep string, onlyValues, includeEmpty bool, exceptKeys ...string) string {
  87. var list []string
  88. var keyList []string
  89. m := make(map[string]int)
  90. if len(exceptKeys) > 0 {
  91. for _, except := range exceptKeys {
  92. m[except] = 1
  93. }
  94. }
  95. for k := range data {
  96. if _, ok := m[k]; ok {
  97. continue
  98. }
  99. value := data[k]
  100. if !includeEmpty && value == "" {
  101. continue
  102. }
  103. if onlyValues {
  104. keyList = append(keyList, k)
  105. } else {
  106. list = append(list, fmt.Sprintf("%s%s%s", k, KeyValueSep, value))
  107. }
  108. }
  109. if onlyValues {
  110. sort.Strings(keyList)
  111. for _, v := range keyList {
  112. list = append(list, data[v])
  113. }
  114. } else {
  115. sort.Strings(list)
  116. }
  117. return strings.Join(list, sep)
  118. }