From b2ba9c0a8ee182ab5f4e17ef61532b8b4d8dec75 Mon Sep 17 00:00:00 2001 From: Jerry <85411418@qq.com> Date: Sun, 1 Oct 2023 23:09:34 +0800 Subject: [PATCH] add aes encrypt --- alipay/client.go | 45 ++++++++++++++++++++++++++++--------------- alipay/client_test.go | 3 +++ alipay/common_api.go | 6 ++---- doc/alipay.md | 3 +++ 4 files changed, 38 insertions(+), 19 deletions(-) diff --git a/alipay/client.go b/alipay/client.go index 399fb444..17d0d8da 100644 --- a/alipay/client.go +++ b/alipay/client.go @@ -1,10 +1,10 @@ package alipay import ( - "context" "crypto/rsa" "crypto/sha1" "crypto/sha256" + "encoding/base64" "encoding/json" "fmt" "hash" @@ -12,6 +12,7 @@ import ( "time" "github.com/go-pay/gopay" + "github.com/go-pay/gopay/pkg/aes" "github.com/go-pay/gopay/pkg/util" "github.com/go-pay/gopay/pkg/xhttp" "github.com/go-pay/gopay/pkg/xlog" @@ -30,7 +31,8 @@ type Client struct { SignType string AppAuthToken string IsProd bool - bodySize int // http response body size(MB), default is 10MB + aesKey string // biz_content 加密的 AES KEY + ivKey []byte privateKey *rsa.PrivateKey aliPayPublicKey *rsa.PublicKey // 支付宝证书公钥内容 alipayPublicCert.crt autoSign bool @@ -91,18 +93,10 @@ func (a *Client) SetBodySize(sizeMB int) { } } -// Deprecated -// 推荐使用 PostAliPayAPISelfV2() -// 示例:请参考 client_test.go 的 TestClient_PostAliPayAPISelf() 方法 -func (a *Client) PostAliPayAPISelf(ctx context.Context, bm gopay.BodyMap, method string, aliRsp any) (err error) { - var bs []byte - if bs, err = a.doAliPay(ctx, bm, method); err != nil { - return err - } - if err = json.Unmarshal(bs, aliRsp); err != nil { - return err - } - return nil +// SetAESKey 设置 biz_content 的AES加密key,设置此参数默认开启 biz_content 参数加密 +func (a *Client) SetAESKey(aesKey string) { + a.aesKey = aesKey + a.ivKey = []byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} } // Deprecated @@ -197,7 +191,20 @@ func (a *Client) pubParamsHandle(bm gopay.BodyMap, method, bizContent string, au pubBody.Set("auth_token", authToken[0]) } if bizContent != util.NULL { - pubBody.Set("biz_content", bizContent) + if a.aesKey == util.NULL { + pubBody.Set("biz_content", bizContent) + } else { + // AES Encrypt biz_content + encryptBizContent, err := a.encryptBizContent(bizContent) + if err != nil { + return "", fmt.Errorf("EncryptBizContent Error: %w", err) + } + if a.DebugSwitch == gopay.DebugOn { + xlog.Debugf("Alipay_Origin_BizContent: %s", bizContent) + xlog.Debugf("Alipay_Encrypt_BizContent: %s", encryptBizContent) + } + pubBody.Set("biz_content", encryptBizContent) + } } // sign sign, err := a.getRsaSign(pubBody, pubBody.GetString("sign_type")) @@ -242,3 +249,11 @@ func (a *Client) checkPublicParam(bm gopay.BodyMap) { bm.Set("app_auth_token", a.AppAuthToken) } } + +func (a *Client) encryptBizContent(originData string) (string, error) { + encryptData, err := aes.CBCEncrypt([]byte(originData), []byte(a.aesKey), a.ivKey) + if err != nil { + return "", err + } + return base64.StdEncoding.EncodeToString(encryptData), nil +} diff --git a/alipay/client_test.go b/alipay/client_test.go index 887db588..a6885a4f 100644 --- a/alipay/client_test.go +++ b/alipay/client_test.go @@ -42,6 +42,9 @@ func TestMain(m *testing.M) { SetReturnUrl("https://www.fmm.ink"). SetNotifyUrl("https://www.fmm.ink") + // 设置biz_content加密KEY,设置此参数默认开启加密(目前未测试成功) + //client.SetAESKey("KvKUTqSVZX2fUgmxnFyMaQ==") + // 自动同步验签(只支持证书模式) // 传入 支付宝公钥证书 alipayPublicCert.crt 内容 client.AutoVerifySign(cert.AlipayPublicContentRSA2) diff --git a/alipay/common_api.go b/alipay/common_api.go index d435f302..2dc3cd99 100644 --- a/alipay/common_api.go +++ b/alipay/common_api.go @@ -34,8 +34,7 @@ func FormatURLParam(body gopay.BodyMap) (urlParam string) { // encryptedData:包括敏感数据在内的完整用户信息的加密数据 // secretKey:AES密钥,支付宝管理平台配置 // beanPtr:需要解析到的结构体指针 -// 文档:https://opendocs.alipay.com/mini/introduce/aes -// 文档:https://opendocs.alipay.com/open/common/104567 +// 文档:https://opendocs.alipay.com/common/02mse3 func DecryptOpenDataToStruct(encryptedData, secretKey string, beanPtr any) (err error) { if encryptedData == util.NULL || secretKey == util.NULL { return errors.New("encryptedData or secretKey is null") @@ -76,8 +75,7 @@ func DecryptOpenDataToStruct(encryptedData, secretKey string, beanPtr any) (err // DecryptOpenDataToBodyMap 解密支付宝开放数据到 BodyMap // encryptedData:包括敏感数据在内的完整用户信息的加密数据 // secretKey:AES密钥,支付宝管理平台配置 -// 文档:https://opendocs.alipay.com/mini/introduce/aes -// 文档:https://opendocs.alipay.com/open/common/104567 +// 文档:https://opendocs.alipay.com/common/02mse3 func DecryptOpenDataToBodyMap(encryptedData, secretKey string) (bm gopay.BodyMap, err error) { if encryptedData == util.NULL || secretKey == util.NULL { return nil, errors.New("encryptedData or secretKey is null") diff --git a/doc/alipay.md b/doc/alipay.md index 3aa85e8c..88aae8fd 100644 --- a/doc/alipay.md +++ b/doc/alipay.md @@ -49,6 +49,9 @@ SetReturnUrl("https://www.fmm.ink"). // 设置返回URL SetNotifyUrl("https://www.fmm.ink"). // 设置异步通知URL SetAppAuthToken() // 设置第三方应用授权 +// 设置biz_content加密KEY,设置此参数默认开启加密 +client.SetAESKey("1234567890123456") + // 自动同步验签(只支持证书模式) // 传入 alipayPublicCert.crt 内容 client.AutoVerifySign([]byte("alipayPublicCert.crt bytes"))