ArtisanCloud / PowerWeChat

PowerWechat是一款基于WeChat SDK for Golang,支持小程序、微信支付、企业微信、公众号等全微信生态
https://powerwechat.artisan-cloud.com
MIT License
1.3k stars 164 forks source link

分账接口没有加密请求中的 `分账个人接收方姓名` 导致报错 #275

Closed moonheart closed 1 year ago

moonheart commented 1 year ago

文档

请求参数中的 "分账个人接收方姓名" 没有经过加密就直接发送出去了

分账接收方类型是MERCHANT_ID时,是商户全称(必传),当商户是小微商户或个体户时,是开户人姓名 分账接收方类型是PERSONAL_OPENID时,是个人姓名(选传,传则校验) 1、此字段需要加密,加密方法详见:敏感信息加密说明 2、使用微信支付平台证书中的公钥:获取平台证书 3、使用RSAES-OAEP算法进行加密 4、将请求中HTTP头部的Wechatpay-Serial设置为证书序列号

Matrix-X commented 1 year ago

你好,感谢你的使用。

我在develop开发分支中,做了相应的调整,添加了全局的RsaOAEP,可以对数据进行RSAES-OAEP算法进行加密。 也同时对这两个接口,加了加密name的处理。

请尝试着使用develop分支调试你的业务,如果有问题,希望可以在你本地调试,修改,提出PR。

https://github.com/ArtisanCloud/PowerWeChat/tree/develop

Matrix-X commented 1 year ago

如果需要高效解决问题,可以加我的企业微信,我可以远程配合调试,谢谢!

moonheart commented 1 year ago

我看到文档里需要去请求一个 api 下载 rsa 公钥 https://pay.weixin.qq.com/wiki/doc/api/tools/mch_pay_yhk.php?chapter=25_7&index=4 , 这个能否内置到 sdk 里, 或者提供一个方法出来给使用方调用?

Matrix-X commented 1 year ago

这个接口应该加上去,我看时间,我空了可以加上去你测试一下。

不过咱们先把上面那个问题先解决,打一个版本。 请问你那两个有测试过么?

moonheart commented 1 year ago

测试了, 提示需要配置 rsa 公钥, 获取 rsa 公钥需要调用这个 api, 调用需要签名, 我这儿还没有找到比较方便的方式去调用, 所以希望加上这个方法

Matrix-X commented 1 year ago

公钥也可以直接在后台下载的,加企业微信聊吧,先解决这个问题

Matrix-X commented 1 year ago

添加了 PaymentApp.Security.GetPublicKey(c.Request.Context())

image image

该接口,我调试成功了,你可以试试。。。在develop分支

moonheart commented 1 year ago

我把公钥配置好测试了下, 发现 comp.RsaOAEP 是空的, image

这里似乎没有给 RsaOAEP 字段赋值: https://github.com/ArtisanCloud/PowerWeChat/blob/f478293ccef154f56ff43e14ef4615a96d4b4032/src/payment/kernel/baseClient.go#L30-L59 唯一有赋值的地方是下面这里, 但是payment的 NewBaseClient 不知道为啥没有调用这个方法, 而是直接创建了 struct, 可能是漏掉了 https://github.com/ArtisanCloud/PowerWeChat/blob/f478293ccef154f56ff43e14ef4615a96d4b4032/src/kernel/baseClient.go#L50-L100

Matrix-X commented 1 year ago

ok,我这里先确保一下对象生成,明天帮你看看

Matrix-X commented 1 year ago

我把公钥配置好测试了下, 发现 comp.RsaOAEP 是空的, image

这里似乎没有给 RsaOAEP 字段赋值:

https://github.com/ArtisanCloud/PowerWeChat/blob/f478293ccef154f56ff43e14ef4615a96d4b4032/src/payment/kernel/baseClient.go#L30-L59

唯一有赋值的地方是下面这里, 但是payment的 NewBaseClient 不知道为啥没有调用这个方法, 而是直接创建了 struct, 可能是漏掉了 https://github.com/ArtisanCloud/PowerWeChat/blob/f478293ccef154f56ff43e14ef4615a96d4b4032/src/kernel/baseClient.go#L50-L100

刚调试了一下,因为是在初始化的时候,我判断,如果启动没有配置rsa_public_key_path,咋不需要给到RsaOAEP。我可以优化一下。但是这样也显示出,你下载的public key ,没有喂给client.RsaOAEP

moonheart commented 1 year ago

image

rsa_public_key_path是配置了的; 但 RsaOAEP 为空.

你说的这个判断是写在 src/kernel/baseClient.go 里面的 NewBaseClient 的, 但是 src/payment/kernel/baseClient.go 没有调用这个方法, 它直接创建了 kernel.BaseClient 结构体, 没有走到这个 rsa_public_key_path 的判断

Matrix-X commented 1 year ago

你好,我又重新看了一遍:

1、此字段需要加密,加密方法详见:敏感信息加密说明 2、使用微信支付平台证书中的公钥:获取平台证书 3、使用RSAES-OAEP算法进行加密 4、将请求中HTTP头部的Wechatpay-Serial设置为证书序列号

而针对第二条,获取平台证书,应该是直接通过后台去下载,我不太清楚为什么会直接跳转到你想要的那个接口

1 敏感信息加密说明 https://pay.weixin.qq.com/wiki/doc/apiv3/wechatpay/wechatpay4_3.shtml

2 获取平台证书 虽然这个也是说用接口下载,但是这个也是证书的维护接口。 https://pay.weixin.qq.com/wiki/doc/apiv3/apis/wechatpay5_1.shtml

image

我现在提交到develop分支,用现在使用这个证书,进行数据加密是可以加密成功的

image

请试一下

moonheart commented 1 year ago

我用最新的代码测试了, 报错 {"code":"PARAM_ERROR","message":"平台证书序列号Wechatpay-Serial错误"}, 同样的配置, 我使用微信官方 sdk 是正常调用的.

对比了下二者的请求信息, 官方sdk发送的请求里的 Wechatpay-Serial header 并不是我配置的证书序列号,而 powerwechat 的请求header Wechatpay-Serial 是我配置的证书序列号.

经过排查, 这个 name 字段应该是用 微信支付平台证书公钥进行加密, 而不是用 商户自己的 API 证书公钥, Wechatpay-Serial header 也应该设置为 微信支付平台证书 的序列号.

微信支付会不定期地更换 微信支付平台证书 以确保交易安全, 所以需要通过 获取平台证书列表 这个接口来定期拉取.

powerwechat 应该在启动时 或者在 第一次使用 加密功能时 去拉取最新的 微信支付平台证书, 并且需要维护一个定时任务用于定期更新此证书.

Matrix-X commented 1 year ago

了解,谢谢你的深入测试

  1. 我需要追加一个获取证书列表的接口
  2. 我需要有一个拉新最新证书列表的机制
  3. 至于定时任务,我理解不应该在sdk中实现,而是需要把第二个刷新获微信支付平台的证书列表的机制,可以让用户去触发或者配置到用户的定时任务中去。这个我们团队会想想。

第一个任务我会先完成,第二个任务我会抓紧追加上去。最近还是在忙些新的项目。

希望可以添加企业微信,进一步沟通,谢谢!

Matrix-X commented 1 year ago

你好,周末梳理了一下,请查阅版本v3.0.21

该版本添加了三个环境变量设置:

文档描述:https://powerwechat.artisan-cloud.com/zh/payment/security.html#商户api私钥

添加获取证书列表的接口,用户可以调用接口,下载保存,列表中已经存有WechatPaySerial,用于V3支付接口。添加分账接收方和分账订单接口,我们这里也验证通过了。 RSA Public Key是之前V2的支付接口使用,我们也测试通过了,也是有同样的接口获取。

可以参考Tutorial的代码演示,包含了

APIGetCertificates

APIDecryptCertificate

APIGetRSAPublicKey

至于你提到的定时任务,这个可能暂时我们PowerWechat3.0暂时不支持,如果你有兴趣,欢迎PR,谢谢!

再次感谢你的使用。