Просмотр исходного кода

新增阿里根证书 sn 提取支持

wziww 6 лет назад
Родитель
Сommit
cfe0351edb
5 измененных файлов с 64 добавлено и 7 удалено
  1. 2 2
      README.md
  2. 8 2
      alipay_client_test.go
  3. 1 1
      alipay_params.go
  4. 49 0
      alipay_service_api.go
  5. 4 2
      examples/alipay/alipay_ServiceApi.go

+ 2 - 2
README.md

@@ -85,7 +85,7 @@
 
 ### 支付宝公共API
 
-* gopay.GetCertSN() => 获取证书SN号(app_cert_sn、alipay_cert_sn、alipay_root_cert_sn<支付宝root根证书的sn获取有问题>)
+* gopay.GetCertSN() => 获取证书SN号(app_cert_sn、alipay_cert_sn、alipay_root_cert_sn<支付宝root根证书的sn获取通过 gopay.GetRootCertSN() 获取>)
 * gopay.AliPaySystemOauthToken() => 换取授权访问令牌(得到access_token,user_id等信息)
 * gopay.FormatPrivateKey() => 格式化应用私钥
 * gopay.FormatAliPayPublicKey() => 格式化支付宝公钥
@@ -178,7 +178,7 @@ client := gopay.NewAliPayClient("2016091200494382", privateKey, false)
 
 //设置支付宝请求 公共参数
 //    注意:具体设置哪些参数,根据不同的方法而不同,此处列举出所以设置参数
-client.SetAliPayRootCertSN().               //设置支付宝根证书SN,通过 gopay.GetCertSN() 获取
+client.SetAliPayRootCertSN().               //设置支付宝根证书SN,通过 gopay.GetRootCertSN() 获取
     SetAppCertSN().                         //设置应用公钥证书SN,通过 gopay.GetCertSN() 获取
     SetCharset("utf-8").                    //设置字符编码,不设置默认 utf-8
     SetSignType("RSA2").                    //设置签名类型,不设置默认 RSA2

+ 8 - 2
alipay_client_test.go

@@ -71,8 +71,6 @@ func TestSubString(t *testing.T) {
 }
 
 func TestGetCertSN(t *testing.T) {
-	//sn, err := GetCertSN("alipay_cert/alipayCertPublicKey_RSA2.crt")
-	//sn, err := GetCertSN("alipay_cert/appCertPublicKey.crt")
 	sn, err := GetCertSN("alipay_cert/alipayRootCert.crt")
 	if err != nil {
 		fmt.Println("err:", err)
@@ -80,6 +78,14 @@ func TestGetCertSN(t *testing.T) {
 	}
 	fmt.Println("sn:", sn)
 }
+func TestGetRootCertSN(t *testing.T) {
+	sn, err := GetRootCertSN("alipay_cert/alipayRootCert.crt")
+	if err != nil {
+		fmt.Println("err:", err)
+		return
+	}
+	fmt.Println("sn:", sn)
+}
 
 func TestDecryptAliPayOpenDataToBodyMap(t *testing.T) {
 	data := "MkvuiIZsGOC8S038cu/JIpoRKnF+ZFjoIRGf5d/K4+ctYjCtb/eEkwgrdB5TeH/93bxff1Ylb+SE+UGStlpvcg=="

+ 1 - 1
alipay_params.go

@@ -44,7 +44,7 @@ func (a *AliPayClient) SetAppCertSN(appCertSN string) (client *AliPayClient) {
 }
 
 //设置 支付宝根证书SN
-//    alipayRootCertSN:支付宝根证书SN,通过 gopay.GetCertSN() 获取
+//    alipayRootCertSN:支付宝根证书SN,通过 gopay.GetRootCertSN() 获取
 func (a *AliPayClient) SetAliPayRootCertSN(alipayRootCertSN string) (client *AliPayClient) {
 	a.AlipayRootCertSN = alipayRootCertSN
 	return a

+ 49 - 0
alipay_service_api.go

@@ -1,6 +1,7 @@
 package gopay
 
 import (
+	"bytes"
 	"crypto"
 	"crypto/aes"
 	"crypto/cipher"
@@ -23,6 +24,19 @@ import (
 	"github.com/tjfoc/gmsm/sm2"
 )
 
+// 允许进行 sn 提取的证书签名算法
+var allowSignatureAlgorithm map[string]bool = map[string]bool{
+	"MD2-RSA":       true,
+	"MD5-RSA":       true,
+	"SHA1-RSA":      true,
+	"SHA256-RSA":    true,
+	"SHA384-RSA":    true,
+	"SHA512-RSA":    true,
+	"SHA256-RSAPSS": true,
+	"SHA384-RSAPSS": true,
+	"SHA512-RSAPSS": true,
+}
+
 //解析支付宝支付完成后的Notify信息
 func ParseAliPayNotifyResult(req *http.Request) (notifyReq *AliPayNotifyRequest, err error) {
 	notifyReq = new(AliPayNotifyRequest)
@@ -269,6 +283,41 @@ Sign:
 	return sn, nil
 }
 
+// GetRootCertSN 阿里根证书 sn 提取
+//    certPath:X.509证书文件路径(appCertPublicKey.crt、alipayRootCert.crt、alipayCertPublicKey_RSA2)
+//    返回 sn:证书序列号(app_cert_sn、alipay_root_cert_sn、alipay_cert_sn)
+//    返回 err:error 信息
+func GetRootCertSN(certPath string) (sn string, err error) {
+	certData, err := ioutil.ReadFile(certPath)
+	if err != nil {
+		return "", err
+	}
+	strs := strings.Split(string(certData), "-----END CERTIFICATE-----")
+	var cert bytes.Buffer
+	for i := 0; i < len(strs); i++ {
+		if strs[i] == "" {
+			continue
+		}
+		if blo, _ := pem.Decode([]byte(strs[i] + "-----END CERTIFICATE-----")); blo != nil {
+			c, err := sm2.ParseCertificate(blo.Bytes)
+			if err != nil {
+				return "", err
+			}
+			si := c.Issuer.String() + c.SerialNumber.String()
+			if !allowSignatureAlgorithm[c.SignatureAlgorithm.String()] {
+				continue
+			}
+			if cert.String() == "" {
+				cert.WriteString(fmt.Sprintf("%x", md5.Sum([]byte(si))))
+			} else {
+				cert.WriteString("_")
+				cert.WriteString(fmt.Sprintf("%x", md5.Sum([]byte(si))))
+			}
+		}
+	}
+	return cert.String(), nil
+}
+
 //解密支付宝开放数据到 结构体
 //    encryptedData:包括敏感数据在内的完整用户信息的加密数据
 //    secretKey:AES密钥,支付宝管理平台配置

+ 4 - 2
examples/alipay/alipay_ServiceApi.go

@@ -74,14 +74,16 @@ func GetCertSN() {
 	}
 	fmt.Println("sn:", sn)
 
-	sn, err = gopay.GetCertSN("alipay_cert/alipayRootCert.crt")
+	sn, err = gopay.GetCertSN("alipay_cert/alipayCertPublicKey_RSA2.crt")
 	if err != nil {
 		fmt.Println("err:", err)
 		return
 	}
 	fmt.Println("sn:", sn)
+}
 
-	sn, err = gopay.GetCertSN("alipay_cert/alipayCertPublicKey_RSA2.crt")
+func GetRootCertSN() {
+	sn, err := gopay.GetRootCertSN("alipay_cert/alipayRootCert.crt")
 	if err != nil {
 		fmt.Println("err:", err)
 		return