Exemple #1
0
        /// <summary>
        /// 获取平台证书的公钥(会从远程请求,不会缓存)
        /// </summary>
        /// <param name="timeOut"></param>
        /// <returns></returns>
        public async Task <PublicKeyCollection> GetPublicKeysAsync(/*int timeOut = Config.TIME_OUT*/)
        {
            var certificates = await CertificatesAsync();

            if (!certificates.ResultCode.Success)
            {
                throw new TenpayApiRequestException("获取证书公钥失败:" + certificates.ResultCode.ErrorMessage);
            }

            if (certificates.data?.Length == 0)
            {
                throw new TenpayApiRequestException("Certificates 获取结果为空");
            }

            PublicKeyCollection keys = new();

            //var tenpayV3Setting = Senparc.Weixin.Config.SenparcWeixinSetting.TenpayV3Setting;//TODO:改成从构造函数配置

            foreach (var cert in certificates.data)
            {
                var publicKey = SecurityHelper.AesGcmDecryptCiphertext(_tenpayV3Setting.TenPayV3_APIv3Key, cert.encrypt_certificate.nonce,
                                                                       cert.encrypt_certificate.associated_data, cert.encrypt_certificate.ciphertext);
                keys[cert.serial_no] = SecurityHelper.GetUnwrapCertKey(publicKey);
            }
            return(keys);
        }
Exemple #2
0
        public void CertificatesTest()
        {
            BasePayApis basePayApis = new BasePayApis();
            var         certs       = basePayApis.CertificatesAsync().GetAwaiter().GetResult();

            Assert.IsNotNull(certs);
            Console.WriteLine(certs.ToJson(true));
            Assert.IsTrue(certs.ResultCode.Success);
            Assert.IsNull(certs.VerifySignSuccess);//不参与验证

            Console.WriteLine();

            var tenpayV3Setting = Senparc.Weixin.Config.SenparcWeixinSetting.TenpayV3Setting;
            var cert            = certs.data.First();
            var pubKey          = SecurityHelper.AesGcmDecryptCiphertext(tenpayV3Setting.TenPayV3_APIv3Key, cert.encrypt_certificate.nonce,
                                                                         cert.encrypt_certificate.associated_data, cert.encrypt_certificate.ciphertext);

            Console.WriteLine(pubKey);
            Assert.IsNotNull(pubKey);
        }
Exemple #3
0
        /// <summary>
        /// 将返回的结果中的ciphertext进行AEAD_AES_256_GCM解反序列化为实体
        /// 签名规则见微信官方文档 https://pay.weixin.qq.com/wiki/doc/apiv3/apis/chapter3_1_5.shtml
        /// </summary>
        /// <param name="aes_key">这里需要传入apiv3秘钥进行AEAD_AES_256_GCM解密 可空</param>
        /// <param name="nonce">加密的随机串 可空</param>
        /// <param name="associated_data">附加数据包 可空</param>
        /// <returns></returns>
        // TODO: 本方法持续测试
        public async Task <T> AesGcmDecryptGetObjectAsync <T>(string aes_key = null, string nonce = null, string associated_data = null) where T : ReturnJsonBase, new()
        {
            aes_key ??= _tenpayV3Setting.TenPayV3_APIv3Key;
            nonce ??= NotifyRequest.resource.nonce;
            associated_data ??= NotifyRequest.resource.associated_data;

            var decrypted_string = SecurityHelper.AesGcmDecryptCiphertext(aes_key, nonce, associated_data, NotifyRequest.resource.ciphertext);

            T result = decrypted_string.GetObject <T>();

            //验证请求签名
            var wechatpayTimestamp = _httpContext.Request.Headers?["Wechatpay-Timestamp"];
            var wechatpayNonce     = _httpContext.Request.Headers?["Wechatpay-Nonce"];
            var wechatpaySignature = _httpContext.Request.Headers?["Wechatpay-Signature"];
            var wechatpaySerial    = _httpContext.Request.Headers?["Wechatpay-Serial"];

            result.VerifySignSuccess = await TenPaySignHelper.VerifyTenpaySign(wechatpayTimestamp, wechatpayNonce, wechatpaySignature, Body, wechatpaySerial, this._tenpayV3Setting);

            result.ResultCode = new TenPayApiResultCode($"{_httpContext.Response.StatusCode} / {_httpContext.Request.Method}", "", "", "", result.VerifySignSuccess == true);

            return(result);
        }