• .net Framwork请求https携带客户端证书


    Hi Everyone,

    SSL双向认证内容,更加安全的连接;

    1、这里将证书安装到“证书 - 当前用户” --> “个人” --> “证书”中;(不会操作的小伙伴百度搜一下吧,我后期维护后再放自己的链接)
    原因是:如果安装到本地计算机了,对于当前用户来说无法越级查找敏感信息。在代码中断点调试后可以确认 --> 证书可以获取,但是获取不到证书中的PrivateKey的,会报异常;

    在这里插入图片描述

    2、MMC中找到客户端证书并双击 / “详细信息” -> 获取指纹:
    在这里插入图片描述

    代码片段如下(注意使用Using,可以释放资源)

    using System;
    using System.Collections.Generic;
    using System.IO;
    using System.Linq;
    using System.Net;
    using System.Security.Cryptography.X509Certificates;
    using System.Threading.Tasks;
    using log4net;
    
    namespace Helper
    {
        public class ServiceHelper
        {
            private static readonly ILog logger = LogManager.GetLogger("ServiceHelper");
            //private readonly string _clientCertificateThumbprint = AppSettingHelper.Read("ServiceClientCertificateThumbprint");
            private readonly string _clientCertificateThumbprint = "上面图片获取的客户端证书指纹";//Client Thumbprint.
    
            /// <summary>
            /// 请求Https并携带客户端证书
            /// </summary>
            /// <param name="content">Request Body</param>
            /// <param name="url">Target URL</param>
            /// <param name="headers">Request Headers</param>
            /// <param name="method">Post、Get.....</param>
            /// <returns></returns>
            public async Task<string> RequestServiceAPI(string content, string url, Dictionary<string, string> headers, string method = "Post")
            {
                try
                {
                    string result = string.Empty;
    
                    #region 方式1:通过mmc安装Client Certificate方式
    
                   
                    ServicePointManager.SecurityProtocol = SecurityProtocolType.Ssl3 | SecurityProtocolType.Tls |
                                                           (SecurityProtocolType)768 | (SecurityProtocolType)3072 |
                                                           (SecurityProtocolType)0x300 | (SecurityProtocolType)0xC00;
    
                    ServicePointManager.ServerCertificateValidationCallback = (sender, certificate, chain, sslPolicyErrors) => true; //获取或设置用于验证服务器证书的回调
                    
                    X509Store store = new X509Store(StoreName.My, StoreLocation.CurrentUser);//从当前用户安装的Client Certificate中进行查找;
                    store.Open(OpenFlags.ReadOnly | OpenFlags.OpenExistingOnly);
                    
                    X509Certificate2 clientCer ;
    
                    try
                    {
                        //do not use "store.Certificates.Find()" --> Performance
                        //Case must be omitted;
                        //Find By certificate thumbprint.
                        clientCer = store.Certificates.Cast<X509Certificate2>().FirstOrDefault(c => c.Thumbprint.Equals(_clientCertificateThumbprint, StringComparison.OrdinalIgnoreCase));
    
                        if (clientCer == null)
                        {
                            logger.Info($"Class : {nameof(ServiceHelper)} Method : {nameof(RequestServiceAPI)}; Error : Client certificate with \"{_clientCertificateThumbprint}\" thumbprint not found.");
                            return null;
                        }
                    }
                    catch
                    {
                        logger.Info($"Class : {nameof(ServiceHelper)} Method : {nameof(RequestServiceAPI)}; Error : Client certificate with \"{_clientCertificateThumbprint}\" thumbprint not found.");
                        return null;
                    }
                    finally
                    {
                        store.Close();
                    }
    
                    #endregion
    
    
                    #region 方式2:通过路径获取Client Certificate方式
    
                    //string certificatePath = @"C:\Users\Admin\Desktop\ClientCertificateFile.pfx";//使用相对路径或者绝对路径
                    //string certPassword = @"pax@4901FL";
    
                    //ServicePointManager.SecurityProtocol = SecurityProtocolType.Ssl3 | SecurityProtocolType.Tls |
                    //                                       (SecurityProtocolType)768 | (SecurityProtocolType)3072 |
                    //                                       (SecurityProtocolType)0x300 | (SecurityProtocolType)0xC00;
    
                    //ServicePointManager.ServerCertificateValidationCallback = (sender, certificate, chain, sslPolicyErrors) => true;
    
                    //X509Certificate2 cer = new X509Certificate2(certificatePath, certPassword, X509KeyStorageFlags.MachineKeySet | X509KeyStorageFlags.PersistKeySet | X509KeyStorageFlags.Exportable);
    
                    #endregion
    
                    byte[] bytes = System.Text.Encoding.UTF8.GetBytes(content);
    
                    HttpWebRequest request = (HttpWebRequest) WebRequest.Create(url);
                    request.ClientCertificates.Add(clientCer);
                    request.ContentType = "application/json";
                    request.Method = method;
                    request.ContentLength = bytes.Length;
                    if (headers != null && headers.Count > 0)
                    {
                        foreach (var item in headers)
                        {
                            request.Headers.Add(item.Key, item.Value);
                        }
                    }
    
                    using (Stream requestStream = request.GetRequestStream())
                    {
                        requestStream.Write(bytes, 0, bytes.Length);
                        requestStream.Close();
                    }
    
                    using (HttpWebResponse response = (HttpWebResponse) await request.GetResponseAsync())
                    {
                        using (Stream responseStream = response.GetResponseStream())
                        {
                            if (responseStream != null)
                            {
                                using (StreamReader reader = new StreamReader(responseStream, System.Text.Encoding.UTF8))
                                {
                                    result = reader.ReadToEnd().Trim();
                                    request.Abort();
                                }
                            }
                        }
                    }
                    
                    return result;
                }
                catch (Exception ex)
                {
                    logger.Info($"Class : {nameof(ServiceHelper)} Method : {nameof(RequestServiceAPI)} happen exception. error: {ex.Message}");
                    return null;
                }
            }
    
    
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124
    • 125
    • 126
    • 127
    • 128
    • 129
    • 130
    • 131
    • 132
    • 133
    • 134
  • 相关阅读:
    阿里P8级大师精品之作:Spring源码深度解读(IOC/AOP/MVC/事务)
    jenkins+nginx部署前端页面&静态资源
    聊聊Vuex原理
    【外汇天眼】MT4 vs MT5:哪个更适合外汇初学者
    linux安装sqoop
    Leetcode290. 单词规律
    <C++>构造_拷贝_析构_运算符重载函数_const成员函数
    【剑指offer】17.打印从1到最大的n位数
    什么是JavaScript中的严格模式(strict mode)?应用场景是什么?
    【暑期每日一题】洛谷 P8301 [CoE R4 A/Stoi2041] 娘子
  • 原文地址:https://blog.csdn.net/qq_39797713/article/details/125446418