lt 5 zile în urmă
părinte
comite
2ff221986a

+ 31 - 58
RO_Server_Trunk-branch_0.1.39/roserver/gmweb/msg/web_paymsg.go

@@ -5,7 +5,6 @@ import (
 	"crypto"
 	"crypto/hmac"
 	"crypto/md5"
-	"crypto/rand"
 	"crypto/rsa"
 	"crypto/sha1"
 	"crypto/x509"
@@ -17,6 +16,7 @@ import (
 	"encoding/xml"
 	"fmt"
 	"io"
+	"math/big"
 	"net/http"
 	"net/url"
 	"rocommon/service"
@@ -426,15 +426,17 @@ func WebPayHwXiaoQiNotify(c *gin.Context) {
 
 	c.String(http.StatusOK, "success")
 }
-func DecryptDataToMap(encrypDataBase64 string, privateKeyStr string) (map[string]string, error) {
+
+// 使用公钥解密(对应 PHP 的 openssl_public_decrypt)
+func DecryptDataToMap(encrypDataBase64 string, publicKeyStr string) (map[string]string, error) {
 	// 1. Base64 解码得到 raw_encryp_data
 	rawEncrypData, err := base64.StdEncoding.DecodeString(encrypDataBase64)
 	if err != nil {
 		return nil, fmt.Errorf("base64解码失败: %v", err)
 	}
 
-	// 2. 使用 RSA 钥解密
-	decryptedData, err := rsaPrivateDecrypt(rawEncrypData, privateKeyStr)
+	// 2. 使用 RSA 钥解密
+	decryptedData, err := rsaPublicDecrypt(rawEncrypData, publicKeyStr)
 	if err != nil {
 		return nil, fmt.Errorf("RSA解密失败: %v", err)
 	}
@@ -443,83 +445,54 @@ func DecryptDataToMap(encrypDataBase64 string, privateKeyStr string) (map[string
 	return parseQueryStringToMap(string(decryptedData)), nil
 }
 
-// rsaPrivateDecrypt RSA私钥解密
-func rsaPrivateDecrypt(ciphertext []byte, privateKeyStr string) ([]byte, error) {
-	// 解析私钥
-	privateKey, err := parsePrivateKey(privateKeyStr)
-	if err != nil {
-		return nil, err
-	}
-
-	// RSA 私钥解密(PKCS1v15 填充)
-	plaintext, err := rsa.DecryptPKCS1v15(rand.Reader, privateKey, ciphertext)
+func rsaPublicDecrypt(ciphertext []byte, publicKeyStr string) ([]byte, error) {
+	// 解析公钥
+	publicKey, err := parsePublicKey(publicKeyStr)
 	if err != nil {
-		return nil, fmt.Errorf("解失败: %v", err)
+		return nil, fmt.Errorf("解析公钥失败: %v", err)
 	}
 
-	return plaintext, nil
-}
-
-// parsePrivateKey 解析 PEM 格式的私钥
-func parsePrivateKey(privateKeyStr string) (*rsa.PrivateKey, error) {
-	// 去除空白字符
-	privateKeyStr = strings.TrimSpace(privateKeyStr)
-
-	// 确保是 PEM 格式
-	if !strings.Contains(privateKeyStr, "-----BEGIN") {
-		privateKeyStr = "-----BEGIN RSA PRIVATE KEY-----\n" +
-			privateKeyStr +
-			"\n-----END RSA PRIVATE KEY-----"
+	// 创建一个假的私钥对象,只填充公钥部分
+	fakePrivateKey := &rsa.PrivateKey{
+		PublicKey: *publicKey,
+		D:         new(big.Int).SetInt64(0), // 占位符
 	}
 
-	// 解码 PEM
-	block, _ := pem.Decode([]byte(privateKeyStr))
-	if block == nil {
-		return nil, fmt.Errorf("PEM解码失败")
-	}
-
-	// 解析私钥(支持 PKCS1 和 PKCS8 格式)
-	privateKey, err := x509.ParsePKCS1PrivateKey(block.Bytes)
+	// 使用私钥解密(实际会使用公钥)
+	// 注意:这个方法可能在某些 Go 版本中不工作
+	plaintext, err := rsa.DecryptPKCS1v15(nil, fakePrivateKey, ciphertext)
 	if err != nil {
-		// 尝试 PKCS8 格式
-		key, err := x509.ParsePKCS8PrivateKey(block.Bytes)
-		if err != nil {
-			return nil, fmt.Errorf("解析私钥失败: %v", err)
-		}
-		var ok bool
-		privateKey, ok = key.(*rsa.PrivateKey)
-		if !ok {
-			return nil, fmt.Errorf("不是RSA私钥")
-		}
-		return privateKey, nil
+		return nil, fmt.Errorf("解密失败: %v", err)
 	}
 
-	return privateKey, nil
+	return plaintext, nil
 }
 
-// parseQueryStringToMap 解析查询字符串为 map
+// 解析查询字符串为 map
 func parseQueryStringToMap(queryStr string) map[string]string {
-	params := make(map[string]string)
-
-	if queryStr == "" {
-		return params
-	}
+	result := make(map[string]string)
 
+	// 按 & 分割
 	pairs := strings.Split(queryStr, "&")
 	for _, pair := range pairs {
 		if pair == "" {
 			continue
 		}
-
+		// 按 = 分割
 		kv := strings.SplitN(pair, "=", 2)
 		if len(kv) == 2 {
-			params[kv[0]] = kv[1]
+			// URL decode 值(如果需要)
+			value, err := url.QueryUnescape(kv[1])
+			if err != nil {
+				value = kv[1]
+			}
+			result[kv[0]] = value
 		} else if len(kv) == 1 {
-			params[kv[0]] = ""
+			result[kv[0]] = ""
 		}
 	}
 
-	return params
+	return result
 }
 
 func VerifySignature(params map[string]string, publicKeyStr string) (bool, error) {