diff --git a/app/http/entities/front/pay.go b/app/http/entities/front/pay.go index 5e0ce7a..14da375 100644 --- a/app/http/entities/front/pay.go +++ b/app/http/entities/front/pay.go @@ -27,8 +27,9 @@ type PayReqs struct { type RefundReqs struct { PayCommonReqBody - OutTradeNo string `json:"out_trade_no" label:"外侧商户订单号"` - OrderId string `json:"order_id" label:"平台订单号"` + RefundOutTradeNo string `json:"refund_out_trade_no" label:"需要退款的外侧商户订单号"` + RefundOrderId string `json:"refundOrder_id" label:"需要退款的平台订单号"` + OutTradeNo string `json:"out_trade_no" validate:"required" label:"外侧商户订单号"` } type PayUrlResp struct { diff --git a/app/http/requestmapping/front.go b/app/http/requestmapping/front.go index 1d87d3d..71d27a2 100644 --- a/app/http/requestmapping/front.go +++ b/app/http/requestmapping/front.go @@ -12,5 +12,6 @@ var FrontRequestMap = map[string]func() (validForm interface{}, isSaveLog bool){ } var FrontRequestMapBeforeDecrypt = map[string]func() interface{}{ - common.FRONT_V1 + "/pay/url": func() interface{} { return new(front.RequestBody) }, + common.FRONT_V1 + "/pay/url": func() interface{} { return new(front.RequestBody) }, + common.FRONT_V1 + "/pay/refund": func() interface{} { return new(front.RequestBody) }, } diff --git a/app/services/apicrypt/rsa.go b/app/services/apicrypt/rsa.go index 0189620..0a90d7f 100644 --- a/app/services/apicrypt/rsa.go +++ b/app/services/apicrypt/rsa.go @@ -13,7 +13,7 @@ func NewRsa(app *appmodel.App) ApiCrypt { } } -func (r *Rsa) Encrypt(data []byte) (encryptData []byte, errCode int) { +func (r *Rsa) Encrypt(data string) (encryptData []byte, errCode int) { if r.App.PublicKey == "" { return nil, errorcode.AppRsaEncryptKeyNotFound } diff --git a/app/services/apicrypt/sm2.go b/app/services/apicrypt/sm2.go index 6d01139..10263df 100644 --- a/app/services/apicrypt/sm2.go +++ b/app/services/apicrypt/sm2.go @@ -12,13 +12,13 @@ func NewSm2(app *appmodel.App) ApiCrypt { } } -func (r *SM2) Encrypt(data []byte) (encryptData []byte, errCode int) { +func (r *SM2) Encrypt(data string) (encryptData []byte, errCode int) { if r.App.MerchantPublicKey == "" { return nil, errorcode.AppSM2EncryptKeyNotFound } - encryptDataString, err := sm2.SM2Encrypt(string(data), r.App.MerchantPublicKey) + encryptDataString, err := sm2.SM2Encrypt(data, r.App.MerchantPublicKey) if err != nil { return nil, errorcode.AppSM2EncryptFail } diff --git a/app/services/apicrypt/sm4.go b/app/services/apicrypt/sm4.go index 9d69f40..b13d290 100644 --- a/app/services/apicrypt/sm4.go +++ b/app/services/apicrypt/sm4.go @@ -13,11 +13,11 @@ func NewSm4(app *appmodel.App) ApiCrypt { } } -func (r *SM4) Encrypt(data []byte) (encryptData []byte, errCode int) { +func (r *SM4) Encrypt(data string) (encryptData []byte, errCode int) { if r.App.MerchantPublicKey == "" || r.App.PrivateKey == "" { return nil, errorcode.AppSM4DecryptKeyNotFound } - encryptDataString, err := sm4.Sm4Encrypt(strconv.FormatInt(r.App.Id, 10), r.App.PrivateKey, r.App.MerchantPublicKey, string(data), "", true) + encryptDataString, err := sm4.Sm4Encrypt(strconv.FormatInt(r.App.Id, 10), r.App.PrivateKey, r.App.MerchantPublicKey, data, "", true) if err != nil { return nil, errorcode.AppSM4EncryptFail } diff --git a/app/services/apicrypt/types.go b/app/services/apicrypt/types.go index df21161..d237b1d 100644 --- a/app/services/apicrypt/types.go +++ b/app/services/apicrypt/types.go @@ -7,7 +7,7 @@ import ( type ( ApiCrypt interface { - Encrypt(data []byte) (encryptData []byte, errCode int) + Encrypt(data string) (encryptData []byte, errCode int) Decrypt(encryptData string) (decryptData []byte, errCode int) } diff --git a/app/services/thirdpay/api/crypt.go b/app/services/thirdpay/api/crypt.go index d78d13e..9e330fd 100644 --- a/app/services/thirdpay/api/crypt.go +++ b/app/services/thirdpay/api/crypt.go @@ -18,15 +18,8 @@ func EnCrypt(app *appmodel.App, data interface{}) ([]byte, int) { if err != nil { return nil, errorcode.AppAesEncryptFail } - //aesKey, err := aes.GenerateRandomStringCrypto(16) - //if err != nil { - // return "", errorcode.AppAesEncryptFail - //} - //aesData, err := aes.Encrypt(dataByte, []byte(aesKey)) - //if err != nil { - // return "", errorcode.AppAesEncryptFail - //} - encryptData, errCode := cryptFunc(appCheck.App).Encrypt(dataByte) + + encryptData, errCode := cryptFunc(appCheck.App).Encrypt(string(dataByte)) if errCode != apicrypt.CryptNotError { return nil, errCode } @@ -46,10 +39,6 @@ func DeCrypt(app *appmodel.App, data string, aesKey string) ([]byte, int) { if len(dataByte) == 0 { return nil, errorcode.AppDeEncryptFail } - //aesData, err := aes.Decrypt(dataByte, []byte(aesKey)) - //if err != nil { - // return nil, errorcode.AppAesEncryptFail - //} return dataByte, errorcode.Success } diff --git a/app/services/thirdpay/pay.go b/app/services/thirdpay/pay.go index 824e6d1..f822970 100644 --- a/app/services/thirdpay/pay.go +++ b/app/services/thirdpay/pay.go @@ -47,7 +47,7 @@ func ThirdPayInfoCheck(ctx context.Context, payReq *front.PayReqs, appCheck *ser func ThirdPayRefund(ctx context.Context, refundReq *front.RefundReqs, appCheck *services.AppCheck, ip string) (refund *thirdpay.Pay) { var req types.Reqs - copier.Copy(req, refundReq) + copier.Copy(&req, refundReq) check := thirdpay.NewPayCheck(&ctx, &req, appCheck, ip) // 校验表单 check.CheckPayInfo() diff --git a/app/utils/encrypt/aes/aes.go b/app/utils/encrypt/aes/aes.go index 24d2772..402130f 100644 --- a/app/utils/encrypt/aes/aes.go +++ b/app/utils/encrypt/aes/aes.go @@ -20,6 +20,13 @@ func Encrypt(plaintext, key []byte) ([]byte, error) { if err != nil { return nil, err } + + // 加密后的数据会比原文长,因为需要添加一些填充字节 + // PKCS#7填充 + plaintext = pkcs7Padding(plaintext, block.BlockSize()) + + // 创建一个cipher.BlockMode,这里使用CBC模式 + // 需要一个iv(初始化向量),它的长度和Block的块大小相同 ciphertext := make([]byte, aes.BlockSize+len(plaintext)) iv := ciphertext[:aes.BlockSize] if _, err := io.ReadFull(rand.Reader, iv); err != nil { @@ -29,7 +36,8 @@ func Encrypt(plaintext, key []byte) ([]byte, error) { mode := cipher.NewCBCEncrypter(block, iv) mode.CryptBlocks(ciphertext[aes.BlockSize:], plaintext) - return iv, nil + // 返回的密文包括iv和加密后的数据 + return ciphertext, nil } // 解密函数 diff --git a/app/utils/encrypt/rsa/rsa.go b/app/utils/encrypt/rsa/rsa.go index 4ce9ff9..e4e02da 100644 --- a/app/utils/encrypt/rsa/rsa.go +++ b/app/utils/encrypt/rsa/rsa.go @@ -32,7 +32,8 @@ func parseRSAPublicKeyFromPEM(pemData []byte) (*rsa.PublicKey, error) { } // encrypt 使用RSA公钥加密数据 -func Encrypt(publicKeyPEM string, plaintext []byte) ([]byte, error) { +func Encrypt(publicKeyPEM string, plaintext string) ([]byte, error) { + var encryptedData []byte // 将PEM编码的公钥转换为[]byte pemData := []byte(publicKeyPEM) @@ -41,14 +42,24 @@ func Encrypt(publicKeyPEM string, plaintext []byte) ([]byte, error) { if err != nil { return nil, err } - + hash := sha256.New() + maxBlockSize := pubKey.Size() - 2*hash.Size() - 2 // 创建用于加密的随机填充 label := []byte("") // OAEP标签,对于某些情况可能是非空的 - ciphertext, err := rsa.EncryptOAEP(sha256.New(), rand.Reader, pubKey, plaintext, label) - if err != nil { - return nil, err + for len(plaintext) > 0 { + blockSize := maxBlockSize + if len(plaintext) < maxBlockSize { + blockSize = len(plaintext) + } + block := plaintext[:blockSize] + encryptedBlock, err := rsa.EncryptOAEP(hash, rand.Reader, pubKey, []byte(block), label) + if err != nil { + return nil, err + } + encryptedData = append(encryptedData, encryptedBlock...) + plaintext = plaintext[blockSize:] } - return ciphertext, nil + return encryptedData, nil } // parseRSAPrivateKeyFromPEM 解析PEM编码的RSA私钥 @@ -80,34 +91,38 @@ func parseRSAPrivateKeyFromPEM(pemData []byte) (*rsa.PrivateKey, error) { // decrypt 使用RSA私钥解密数据 func Decrypt(privateKeyPEM string, encryptedDataBase64 string) ([]byte, error) { + var decryptedData []byte // 将PEM编码的私钥转换为[]byte pemData := []byte(privateKeyPEM) - // 解析PEM数据以获取私钥 privKey, err := parseRSAPrivateKeyFromPEM(pemData) if err != nil { return nil, err } + keySize := privKey.PublicKey.Size() + label := []byte("") // OAEP标签,对于某些情况可能是非空的 + hash := sha256.New() // 将Base64编码的加密数据解码为字节切片 encryptedData, err := base64.StdEncoding.DecodeString(encryptedDataBase64) if err != nil { return nil, err } - - // 根据你的加密方式选择合适的解密函数 - // 这里假设使用的是OAEP填充和SHA-256哈希函数 - label := []byte("") // OAEP标签,对于某些情况可能是非空的 - decrypted, err := rsa.DecryptOAEP(sha256.New(), rand.Reader, privKey, encryptedData, label) - if err != nil { - // 如果失败,可以尝试使用PKCS#1 v1.5填充 - decrypted, err = rsa.DecryptPKCS1v15(rand.Reader, privKey, encryptedData) + for len(encryptedData) > 0 { + block := encryptedData[:keySize] + // 这里假设使用的是OAEP填充和SHA-256哈希函数 + decryptedBlock, err := rsa.DecryptOAEP(hash, rand.Reader, privKey, block, label) if err != nil { - return nil, err + //// 如果失败,可以尝试使用PKCS#1 v1.5填充 + decryptedBlock, err = rsa.DecryptPKCS1v15(rand.Reader, privKey, encryptedData) + if err != nil { + return nil, err + } } + decryptedData = append(decryptedData, decryptedBlock...) + encryptedData = encryptedData[keySize:] } - - return decrypted, nil + return decryptedData, nil } // 生成密钥对 diff --git a/app/utils/encrypt/rsa/rsa_test.go b/app/utils/encrypt/rsa/rsa_test.go index 46e1c60..d6dae86 100644 --- a/app/utils/encrypt/rsa/rsa_test.go +++ b/app/utils/encrypt/rsa/rsa_test.go @@ -18,7 +18,7 @@ func TestRsaEncrypt(t *testing.T) { } func TestRsaDecrypt(t *testing.T) { - data := encrypt() + data := "pPnAPy7v2SY9Fu0LFcQH8UBA6VQ2FCfSg3nRZdMXS7mWjBwlacKHuFnh9UhobL7mxnmMyZPP100bpjCg2kvcfOpOp3ci85p+OYWINt4Fh3qgEOTG5FUyziaagGLm882t/I36KsDTVvbMZvC5sg4gZ9JQ5yAR+nuJfr0IxI0se/iD5luV1rms1kZHggd30iXdZtbkbX7xJ4xtnIiJmZU7kL+Xmvv1rDdPLxbol65QfnM1me1IHkXJapqSBnhEEmFQyBx31vp1ccNjkza8ZWbvTPCngc1k4kvlm6lKfwsG4hMuSdXUzveDm+Oo8StAKnyVoerJ202n7Vfx1XhehineQT0TPD7bO0HCEsDXXYEWwvcax8VdzYvHk7qSbH6e154qCr4LgDRSHKwAAExinTrzxx2rtSimieBLaEpDL2v5ch45HnhjRhWTRmM61W1g6sdHaVX1mQxaXvrT4v+h+f4TbIV4r4qeGJ6rXG+yKRoYseLzyGgystoOny9P0UH15W8rWPytV2eioWT7i3Cglg04BWP9mst67LQXeFH4CA6CkwVV2w9nCHrzxX2ouYSQELUEkTlIMry2AlkZubUnupGJLmLLUyZj7pM/6cLjyAgm02/gRc4wwf7JBBq/ipmKXpkhHXWLtQDWJEZTT+ug2v9EXy5dgPNPe8ZI0MILAeipjIc=" privateKeyPEM := `-----BEGIN RSA PRIVATE KEY----- ` + PRI + ` -----END RSA PRIVATE KEY-----` @@ -27,13 +27,11 @@ func TestRsaDecrypt(t *testing.T) { } func encrypt() string { - data := "{\"order_no\":4323455642275676219,\"order_type\":1,\"out_tread_no\":\"asdadasdas\",\"amount\":1,\"desc\":\"abc\",\"status\":2,\"create_time\":\"2024-08-07 18:36:43\"}" - fmt.Println(len(data)) - dataJson := []byte(data) + data := "{\"pay_channel_id\":8935141660703064070,\"out_trade_no\":\"refundOutTreadNo001\",\"amount\":1,\"desc\":\"退款\",\"ext_json\":\"\",\"app_id\":5476377146882523138,\"timestamp\":53612533412643,\"refund_out_trade_no\":\"asdadasdas\"}" pub := `-----BEGIN PUBLIC KEY----- ` + PUB + ` -----END PUBLIC KEY-----` - en, err := Encrypt(pub, dataJson) + en, err := Encrypt(pub, data) if err != nil { panic(err) } @@ -42,9 +40,10 @@ func encrypt() string { } func encryptWithAes() string { - data := "{\"pay_channel_id\":8935141660703064070,\"out_trade_no\":\"asdadasdas\",\"order_type\":1,\"amount\":1,\"desc\":\"abc\",\"ext_json\":\"\",\"app_id\":5476377146882523138,\"timestamp\":53612533412643}" + data := "{\"pay_channel_id\":8935141660703064070,\"out_trade_no\":\"refundOutTreadNo001\",\"amount\":1,\"desc\":\"退款\",\"ext_json\":\"\",\"app_id\":5476377146882523138,\"timestamp\":53612533412643,\"refund_out_trade_no\":\"asdadasdas\"}" aes.Encrypt([]byte(data), []byte(aes.TestKey)) - dataJson := []byte(data) + + dataJson := base64.StdEncoding.EncodeToString([]byte(data)) pub := `-----BEGIN PUBLIC KEY----- ` + PUB + ` -----END PUBLIC KEY-----` @@ -58,14 +57,7 @@ func encryptWithAes() string { // 测试生成密钥对 func TestGenerateRSAKey(t *testing.T) { - pub, pri, err := GenerateKey() - data := "{\"pay_channel_id\":8935141660703064070,\"out_trade_no\":\"asdadasdas\",\"order_type\":1,\"amount\":1,\"desc\":\"abc\",\"ext_json\":\"\",\"app_id\":5476377146882523138,\"timestamp\":53612533412643}" - dataJson := []byte(data) - en, err := Encrypt(pub, dataJson) - if err != nil { - panic(err) - } - content := base64.StdEncoding.EncodeToString(en) - res, err := Decrypt(pri, content) - fmt.Println("解密", string(res), err) + pub, pri, _ := GenerateKey() + + fmt.Println("pub:", pub, "\n", "pri:", pri) }