浮沉与木

.NET接入微信支付(四)平台证书

电脑版发表于:2023/2/23 17:05
    /// <summary>
    /// 平台证书类
    /// </summary>
    public class WxPayPlateformCertificate
    {
        public string serial_no { get; set; }

        public DateTimeOffset effective_time { get; set; }

        public DateTimeOffset expire_time { get; set; }

        public EncryptInfo encrypt_certificate { get; set; }

        InMemoryCertificateManager certificateManager = InMemoryCertificateManager.Instance;

        /// <summary>
        /// 获取平台证书
        /// </summary>
        /// <param name="serialNo"></param>
        /// <param name="options"></param>
        /// <returns></returns>
        public X509Certificate2 GetPlatformCertificate(string url, string serialNo, string secretKey)
        {
            var certificate = certificateManager.GetCertificate(serialNo);

            if (certificate != null)
            {
                return certificate;
            }
            Logger loger = LogManager.GetCurrentClassLogger();

            loger.Info("更新平台证书:" + DateTime.Now.ToString("yyyy-MM-dd hh:mm:ss"));

            var response = HttpService.Execute("", url, "GET");

            if (string.IsNullOrWhiteSpace(response) || response.Length == 0)
            {
                throw new Exception("GET PLATFORM CERTIFICATE FAILED! 获取平台证书失败!");
            }

            JObject jObject = JObject.Parse(response);

            string resultStr = jObject["data"].ToString();

            List<WxPayPlateformCertificate> platformCertificates = resultStr.FromJsonObj<List<WxPayPlateformCertificate>>();

            foreach (var item in platformCertificates)
            {
                switch (item.encrypt_certificate.algorithm)
                {
                    case "AEAD_AES_256_GCM":
                        {
                            serialNo = item.serial_no;
                            certificateManager.SetCertificate(item.serial_no, new X509Certificate2(WxPayDecrypt.Decrypt(secretKey, item.encrypt_certificate)));
                        }
                        break;
                    default:
                        throw new Exception("Unsupported Encrypt Algorithm!");
                }
            }
            return certificateManager.GetCertificate(serialNo);
        }
    }
        /// <summary>
    /// 微信商户平台证书管理器接口。
    /// </summary>
    public abstract class CertificateManager
    {
        /// <summary>
        /// 根据证书序列号获取证书(cer 格式)。
        /// </summary>
        /// <param name="serialNumber"></param>
        /// <returns></returns>
        public abstract X509Certificate2 GetCertificate(string serialNumber);

        /// <summary>
        /// 设置证书序列号与证书(cer 格式)的映射关系。
        /// </summary>
        /// <param name="serialNumber"></param>
        /// <param name="certificate"></param>
        public abstract void SetCertificate(string serialNumber, X509Certificate2 certificate);
    }

    /// <summary>
    /// 一个基于内存实现的 <see cref="CertificateManager"/>。
    /// </summary>
    public class InMemoryCertificateManager : CertificateManager
    {
        private IDictionary<string, X509Certificate2> _dict;
        private static object lockObject = new object();
        static InMemoryCertificateManager _;
        public static InMemoryCertificateManager Instance
        {
            get
            {
                if (_ == null)
                {
                    lock (lockObject)
                    {
                        if (_ == null)
                            _ = new InMemoryCertificateManager();
                    }
                }
                return _;
            }
        }

        private InMemoryCertificateManager()
        {
            _dict = new ConcurrentDictionary<string, X509Certificate2>();
        }

        public override X509Certificate2 GetCertificate(string serialNumber)
        {
            if (serialNumber == null) throw new ArgumentNullException(nameof(serialNumber));

            return _dict[serialNumber];
        }

        public override void SetCertificate(string serialNumber, X509Certificate2 certificate)
        {
            if (serialNumber == null) throw new ArgumentNullException(nameof(serialNumber));
            if (certificate == null) throw new ArgumentNullException(nameof(certificate));

            _dict[serialNumber] = certificate;
        }
    }


关于TNBLOG
TNBLOG,技术分享。技术交流:群号677373950
ICP备案 :渝ICP备18016597号-1
App store Android
精彩评论
{{item.replyName}}
{{item.content}}
{{item.time}}
{{subpj.replyName}}
@{{subpj.beReplyName}}{{subpj.content}}
{{subpj.time}}
猜你喜欢