fudiwei / DotNetCore.SKIT.FlurlHttpClient.Wechat

可能是全网最完整的 C# 版微信 SDK,封装全部已知的微信 OpenAPI,包含微信公众平台(订阅号+服务号+小程序+小游戏+小商店+视频号)、微信开放平台、微信商户平台(微信支付+微企付)、企业微信、微信广告平台、微信智能对话开放平台等模块,可跨平台。持续随官方更新,欢迎 Star/Fork/PR。QQ 交流群 875580418【满】、930461548【满】、611974621。
https://github.com/fudiwei/DotNetCore.SKIT.FlurlHttpClient
MIT License
1.43k stars 283 forks source link

验证回调通知事件签名提示:Signature does not match #139

Closed Lingweiy closed 2 months ago

Lingweiy commented 2 months ago

想问下调用VerifyEventSignatureAsync提示(Signature does not match)是什么原因? Signature does not match. Maybe "JrJT0uT4TKpnqka6mLemixE2Gy5JShpkctrX7gfjiVYCvHAvze3dVIvaTcU/e2tQ1Ises/2w4qsbmG6huw4L5fmz/XqvboxGNNj92z3Y2JgyC4LcZzUtvpiaRObwr8vF6cd53IGrCRg0OOgFC8BtgxgvNGjtFyEOc4cakkj7xDOe2MMue7hP35x1+ZEyWOp2TyiqlQPeZScoMaXDsNEBCjaGRsiRGCVNnR6UDx417kuH3G09601mtBozMte9+t97mBYCSOoNOoXC3pZvfFclzZgibCX3hZs8kJSFcNoJ+3K/nbrnivgOj3ddzo8Np35yYgIj3Pvpjg4WdHQLApcprA==" is an illegal signature. 使用的就是请求头微信返回的签名字段(Wechatpay-Signature),ExecuteQueryCertificatesAsync拿到的平台证书我也调用(DecryptResponseSensitiveProperty)解密了 CertificateEntry里的AlgorithmType是“RSA”,是否应该是“WECHATPAY2-SHA256-RSA2048”是这个原因吗? PS.我将AlgorithmType改为“AlgorithmType”,会提示我:The value of algorithmType an invalid value. (Parameter 'algorithmType') image

fudiwei commented 2 months ago

字面意思,签名错误。

可能传参错误、混用了不同商户号(即用商户A去验签商户B的回调)等原因。

请贴下完整代码看看。

Lingweiy commented 2 months ago

目前还没支持多商户号,只配置了一个商户号,应该不是混用的原因。 这是Controller: image 这是service: image image 后面的 DecryptEventResource 方法是可以解密出来数据的

fudiwei commented 2 months ago

image

你应该使用收到的原始数据验签,而不是先反序列化后再序列化回 JSON 字符串 —— 你无法保证你序列化出来的结果跟你收到的是一模一样的。

Lingweiy commented 2 months ago

原来是这样,感谢大神指点! image

因为一直读不到Request.Body,用 Sample 里读取body的方式也不行,最后无奈选择了这种方式...我再研究下

Lingweiy commented 2 months ago

定位到了问题,我定义input的时候字段的顺序与官方文档的顺序的不一致,将顺序修改成一样后,还是使用上面的方式将input反序列化后验签,可以通过了! 感谢大神指点~

fudiwei commented 2 months ago

定位到了问题,我定义input的时候字段的顺序与官方文档的顺序的不一致,将顺序修改成一样后,还是使用上面的方式将input反序列化后验签,可以通过了! 感谢大神指点~

不建议你这么搞。以后微信突然调整字段顺序了你怎么办?或者人家传给你的 JSON 里突然多了空格怎么办?

{ "key1": "value1", "key2": "value2" }

{"key2":"value2","key1":"value1"}

虽然一个有空格一个没空格、键顺序也不一样,但从数据的角度上讲,这俩 JSON 完全一样。可从字符串上看,这就是俩不同的字符串,当然签名结果会不一样。

REF: https://pay.weixin.qq.com/docs/merchant/development/interface-rules/signature-verification.html

image

微信官方也强调了,要使用原始报文主体验签。

Lingweiy commented 2 months ago

好的,感谢大神指出问题~ 现在框架使用的是 ASP.NET Core 8,读取 Request.Body 的方式应该是变化了,我再查查文档,优化成使用原始报文主体验签。