From 076fbd4a9dc688c76455a911aca7d8ad0475f1fd Mon Sep 17 00:00:00 2001 From: Fu Diwei Date: Mon, 2 Aug 2021 21:51:46 +0800 Subject: [PATCH] =?UTF-8?q?feat(work):=20=E6=96=B0=E5=A2=9E=E9=AA=8C?= =?UTF-8?q?=E8=AF=81=E4=BC=81=E4=B8=9A=E5=BE=AE=E4=BF=A1=E5=9B=9E=E8=B0=83?= =?UTF-8?q?=E9=80=9A=E7=9F=A5=E4=BA=8B=E4=BB=B6=E7=9A=84=E6=89=A9=E5=B1=95?= =?UTF-8?q?=E6=96=B9=E6=B3=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../WechatWorkClientEventExtensions.cs | 114 ++++++++++++++++++ 1 file changed, 114 insertions(+) diff --git a/src/SKIT.FlurlHttpClient.Wechat.Work/Extensions/WechatWorkClientEventExtensions.cs b/src/SKIT.FlurlHttpClient.Wechat.Work/Extensions/WechatWorkClientEventExtensions.cs index e2c800bd..db268076 100644 --- a/src/SKIT.FlurlHttpClient.Wechat.Work/Extensions/WechatWorkClientEventExtensions.cs +++ b/src/SKIT.FlurlHttpClient.Wechat.Work/Extensions/WechatWorkClientEventExtensions.cs @@ -2,6 +2,7 @@ using System.IO; using System.Text; using System.Text.RegularExpressions; +using System.Xml.Linq; using System.Xml.Serialization; namespace SKIT.FlurlHttpClient.Wechat.Work @@ -249,5 +250,118 @@ namespace SKIT.FlurlHttpClient.Wechat.Work return xml; } + + /// + /// 验证回调通知事件签名。 + /// REF: https://open.work.weixin.qq.com/api/doc/90000/90139/90968 + /// REF: https://open.work.weixin.qq.com/api/doc/90001/90148/91144 + /// REF: https://open.work.weixin.qq.com/api/doc/90002/90156/91169 + /// + /// + /// 微信回调通知中的 timestamp 字段。 + /// 微信回调通知中的 nonce 字段。 + /// 微信回调通知中的 echostr 字段。 + /// 微信回调通知中的 msg_signature 字段。 + /// + /// + public static bool VerifyEventSignatureForEcho(this WechatWorkClient client, string callbackTimestamp, string callbackNonce, string callbackEcho, string callbackSignature, out string? replyEcho) + { + if (client == null) throw new ArgumentNullException(nameof(client)); + if (callbackTimestamp == null) throw new ArgumentNullException(nameof(callbackTimestamp)); + if (callbackNonce == null) throw new ArgumentNullException(nameof(callbackNonce)); + if (callbackEcho == null) throw new ArgumentNullException(nameof(callbackEcho)); + if (callbackSignature == null) throw new ArgumentNullException(nameof(callbackSignature)); + + try + { + bool ret = Utilities.WxBizMsgCryptor.VerifySignature( + sToken: client.Credentials.PushToken!, + sTimestamp: callbackTimestamp, + sNonce: callbackNonce, + sMsgEncrypt: callbackEcho, + sMsgSign: callbackSignature + ); + + if (ret) + { + replyEcho = Utilities.WxBizMsgCryptor.AESDecrypt(cipherText: callbackEcho, encodingAESKey: client.Credentials.PushEncodingAESKey!, out _); + return true; + } + } + catch { } + + replyEcho = null; + return false; + } + + /// + /// 验证回调通知事件签名。 + /// REF: https://open.work.weixin.qq.com/api/doc/90000/90139/90968 + /// REF: https://open.work.weixin.qq.com/api/doc/90001/90148/91144 + /// REF: https://open.work.weixin.qq.com/api/doc/90002/90156/91169 + /// + /// + /// 微信回调通知中的 timestamp 字段。 + /// 微信回调通知中的 nonce 字段。 + /// 微信回调通知中请求正文(JSON 格式)。 + /// 微信回调通知中的 msg_signature 字段。 + /// + public static bool VerifyEventSignatureFromJson(this WechatWorkClient client, string callbackTimestamp, string callbackNonce, string callbackJson, string callbackSignature) + { + if (client == null) throw new ArgumentNullException(nameof(client)); + if (callbackJson == null) throw new ArgumentNullException(nameof(callbackJson)); + + try + { + var encryptedEvent = client.JsonSerializer.Deserialize(callbackJson); + return Utilities.WxBizMsgCryptor.VerifySignature( + sToken: client.Credentials.PushToken!, + sTimestamp: callbackTimestamp, + sNonce: callbackNonce, + sMsgEncrypt: encryptedEvent.EncryptedData, + sMsgSign: callbackSignature + ); + } + catch + { + return false; + } + } + + /// + /// 验证回调通知事件签名。 + /// REF: https://open.work.weixin.qq.com/api/doc/90000/90139/90968 + /// REF: https://open.work.weixin.qq.com/api/doc/90001/90148/91144 + /// REF: https://open.work.weixin.qq.com/api/doc/90002/90156/91169 + /// + /// + /// 微信回调通知中的 timestamp 字段。 + /// 微信回调通知中的 nonce 字段。 + /// 微信回调通知中请求正文(XML 格式)。 + /// 微信回调通知中的 msg_signature 字段。 + /// + public static bool VerifyEventSignatureFromXml(this WechatWorkClient client, string callbackTimestamp, string callbackNonce, string callbackXml, string callbackSignature) + { + if (client == null) throw new ArgumentNullException(nameof(client)); + if (callbackXml == null) throw new ArgumentNullException(nameof(callbackXml)); + + try + { + XDocument xDoc = XDocument.Parse(callbackXml); + string? msgEncrypt = xDoc.Root?.Element("Encrypt")?.Value; + + return Utilities.WxBizMsgCryptor.VerifySignature( + sToken: client.Credentials.PushToken!, + sTimestamp: callbackTimestamp, + sNonce: callbackNonce, + sMsgEncrypt: msgEncrypt!, + sMsgSign: callbackSignature + ); + } + catch + { + return false; + } + } } }