评论

【C#】WechatPay-API-v3 使用平台证书加密内容与应答|通知验签(SHA256 with RSA)

官方暂时没有维护应答与通知签名的验证C#示例,找了些资料被困扰了一天终于调试通了,贴出来下 此类提供两个方法: 1.敏感信息加密,如身份证、银行卡号。(特约商户进件接口需要); 2.应答与通知签验签。

/// <summary>

    /// 使用微信支付平台证书公钥加密验签

    /// https://wechatpay-api.gitbook.io/wechatpay-api-v3/qian-ming-zhi-nan-1/qian-ming-yan-zheng

    /// </summary>

    public class WXPlatform

    {

        public string PublicKey { get; private set; }

        private byte[] _publicKeyBytes { get; set; }

        /// <summary>

        /// 构造方法

        /// </summary>

        /// <param name="publickey">-----BEGIN CERTIFICATE----- 开头的string,转为bytes->不需要每次都去</param>

        public WXPlatform(string publickey)

        {

            this.PublicKey = publickey;

            this._publicKeyBytes = Encoding.UTF8.GetBytes(publickey);

        }


        /// <summary>

        /// 最终提交请求时,需对敏感信息加密,如身份证、银行卡号。

        /// 加密算法是RSA,使用从接口下载到的公钥进行加密,非后台下载到的私钥。

        /// </summary>

        /// <param name="text">要加密的明文</param>

        /// <param name="publicKey">  </param>

        /// <returns></returns>

        public string Encrypt(string text)

        {

            var x509 = new X509Certificate2(this._publicKeyBytes);

            using (var rsa = (RSACryptoServiceProvider)x509.PublicKey.Key)

            {

                var buff = rsa.Encrypt(Encoding.UTF8.GetBytes(text), true);

                return Convert.ToBase64String(buff);

            }

        }


        /// <summary>

        /// 验证签名

        /// </summary>

        /// <param name="signedString">私钥加密串-Wechatpay-Signature</param>

        /// <param name="signSourceString">验签名串-应答时间戳\n应答随机串\n应答报文主体\n</param>

        /// <returns></returns>

        public bool VerifySign(string signedString, string signSourceString)

        {

            var x509 = new X509Certificate2(this._publicKeyBytes);

            using (var rsa = (RSACryptoServiceProvider)x509.PublicKey.Key)

            {

                using (var sha256 = new SHA256CryptoServiceProvider())

                {

                    var b = rsa.VerifyData(Encoding.UTF8.GetBytes(signSourceString), sha256, Convert.FromBase64String(signedString));

                    return b;

                }

            }

        }

    }

最后一次编辑于  2020-02-29  
点赞 3
收藏
评论

5 个评论

  • 不知离意
    不知离意
    2021-06-01

    大佬,我这个你知道怎么搞吗?公钥是平台证书拿解密拿的,还有开头和换行符在里面,这里报错说无法将RSACng对象转换成RSacyptologyServiceProvider对象

    2021-06-01
    赞同
    回复 1
    • Sunny浩🌈
      Sunny浩🌈
      2021-09-24
      报错说无法将RSACng对象转换成RSacyptologyServiceProvider对象,你解决了吗
      2021-09-24
      回复
  • 阡陌风狸
    阡陌风狸
    2020-09-25

    我使用这个验签的方法也是报这个错 asp.net core 3 环境

    2020-09-25
    赞同
    回复 3
  • 本王今年八岁
    本王今年八岁
    2020-07-22

    我这边为什么回调没有签名?

    2020-07-22
    赞同
    回复 4
  • 三番聿承
    三番聿承
    2020-07-17

    大佬, 你好, 我想问下, 那个publickey 是通过这个接口(https://api.mch.weixin.qq.com/v3/certificates)获取到的这个字段(ciphertext)的值吗? 我直接用这个值会报错

    2020-07-17
    赞同
    回复 5
    • 三番聿承
      三番聿承
      2020-07-17
      找到了, 用这个解密, aes秘钥是微信支付后台设置的apiv3秘钥
      https://wechatpay-api.gitbook.io/wechatpay-api-v3/qian-ming-zhi-nan-1/zheng-shu-he-hui-tiao-bao-wen-jie-mi
      2020-07-17
      1
      回复
    • 阡陌风狸
      阡陌风狸
      2020-09-24
      这个能在asp.net core 中用吗,我一直都是报错mac check in GCM failed
      2020-09-24
      回复
    • peng
      peng
      2020-09-26回复阡陌风狸
      获得平台证书信息后需要使用apiv3key 解密,然后拿到publikey信息 。楼上链接中有官方.NET解密实现。
      2020-09-26
      回复
    • Sunny浩🌈
      Sunny浩🌈
      2021-09-24回复三番聿承
      解密 拿到 -----BEGIN CERTIFICATE----还是不行,找不到申请的对象是怎么回事呢
      2021-09-24
      回复
    • 八九
      八九
      2023-11-27
      您好,请问问题解决了吗,我也是做到这个位置卡住了,刚接触支付这块,其他大佬分享的也没看懂,我的框架是.net 4.6.1
      2023-11-27
      回复
  • 灰灰
    灰灰
    2020-06-12

    有个疑问?就是验证签名哪个方法,是注释写错了吗?

    官方文档是说:信支付使用商户证书中的公钥对下行的敏感信息进行加密。开发者应使用商户私钥对下行的敏感信息的密文进行解密。你这个验证签名这个方法是用于解密的吧?

    验证签名应该是用公钥验签,官方文档是说:商户的技术人员应使用微信支付平台证书中的公钥验签。

    是这样吗?还是我理解错了?

    2020-06-12
    赞同
    回复 5
    • peng
      peng
      2020-06-12
      注释没有错,这个方法用于验签,而非解密。


      https://wechatpay-api.gitbook.io/wechatpay-api-v3/qian-ming-zhi-nan-1/qian-ming-yan-zheng


      微信支付API v3使用微信支付的平台私钥(不是商户私钥)进行应答签名。相应的,商户的技术人员应使用微信支付平台证书中的公钥验签。
      2020-06-12
      1
      回复
    • 灰灰
      灰灰
      2020-06-12回复peng
      你这样一说我就明白了,
      请问:开发者应使用商户私钥对下行的敏感信息的密文进行解密,这个有对应的方法?
      2020-06-12
      回复
    • 灰灰
      灰灰
      2020-06-12
      看你上面有一个对应的加密,解密方法有嘛
      2020-06-12
      回复
    • peng
      peng
      2020-06-12回复灰灰
      你提的问题我回答了,可以下载文章中的百度分享,你们有代码,解密需要用到外部dll ,里面也有。
      2020-06-12
      回复
    • 灰灰
      灰灰
      2020-06-12回复peng
      好的,谢谢
      2020-06-12
      回复
登录 后发表内容