zoukankan      html  css  js  c++  java
  • .net core下用HttpClient和asp.net core实现https的双向认证

    关于https双向认证的知识可先行google,这时矸接代码。

    为了双向认证,我们首先得准备两个crt证书,一个是client.crt,一个是server.crt,有时为了验证是否同一个根证书的验证,这两个证书可以共有一个根证书root.crt。

    首先要生成这些证书,这里采用了自签证书方式:

    证书生成工具可在这里下载(windows下生成):

    https://github.com/axzxs2001/Asp.NetCoreExperiment/blob/master/Asp.NetCoreExperiment/Certificate/openssl/Win64OpenSSL-1_1_0i.exe

    安装完成后在C:OpenSSL-Win64in(最好不要改路径,否则生成证书时要改配置文件路径)下以管理员运行openssl.exe

    一、创建根证书

    • 生成key文件,输入密码:

      openssl genrsa -des3 -out root.key 

    • 生成请求证书文件,如果安装路径发生改变,可以通过在下面命令后面添加-config openssl.cfg来指明配置文件路径

      openssl req -new -key root.key -out root.csr 

    • 生成一个10年期根证书 root.crt:

      openssl x509 -req -days 3650 -sha1 -extensions v3_ca -signkey root.key -in root.csr -out root.crt 

      分别在客户端或服务端安装根证书,windows上安装证书时,证书存储可选择“受信任的根证书颁发机构”

     

    二、创建服务端证书

    • 生成key文件,输入密码

      openssl genrsa -des3 -out server.key 2048 

    • 生成请求证书文件,如果安装路径发生改变

      openssl req -new -key server.key -out server.csr 

    • 用根证书生成一个10年期证书 server.crt:

      openssl x509 -req -days 3650 -sha1 -extensions v3_req -CA root.crt -CAkey root.key -CAserial root.srl -CAcreateserial -in server.csr -out server.crt 

    • 生成.net core识别的证书文件server.pfx

      openssl pkcs12 -export -in server.crt -inkey server.key -out server.pfx 

    三、创建客户端证书

    • 生成key文件,输入密码

      openssl genrsa -des3 -out client.key 2048 

    • 生成请求证书文件,如果安装路径发生改变

      openssl req -new -key client.key -out client.csr 

    • 用根证书生成一个10年期证书 client.crt:

      openssl x509 -req -days 3650 -sha1 -extensions v3_req -CA root.crt -CAkey root.key -CAserial root.srl -CAcreateserial -in client.csr -out client.crt 

    • 生成.net core识别的证书文件client.pfx

      openssl pkcs12 -export -in client.crt -inkey client.key -out client.pfx 

    接下来创建asp.net core web api项目,并把server.pfx添加到项目中,并设置属性为“始终复制”,接着修改Program.cs下的CreateWebHostBuilder方法就可以:

     1   public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
     2             WebHost.CreateDefaultBuilder(args)
     3                 .UseKestrel(options =>
     4                 {
     5                     options.Listen(IPAddress.Any, 80);
     6                     //启用https,443端口
     7                     options.Listen(IPAddress.Any, 443, listenOptions =>
     8                     {
     9                         var serverCertificate = new X509Certificate2("server.pfx", "ssssss");
    10                         var httpsConnectionAdapterOptions = new HttpsConnectionAdapterOptions()
    11                         {
    12                             ClientCertificateMode = ClientCertificateMode.AllowCertificate,
    13                             SslProtocols = System.Security.Authentication.SslProtocols.Tls12,
    14                             //用chain.Build验证客户端证书
    15                             ClientCertificateValidation = (cer, chain, error) =>
    16                              {   
    17                                  return chain.Build(cer); 
    18                              },
    19                             ServerCertificate = signingCertificate
    20                         };
    21                         listenOptions.UseHttps(httpsConnectionAdapterOptions);
    22                     });
    23                 })
    24                 .UseStartup<Startup>();

    为了区分http和https请求,在HomeController中写如下代码:

     1         [HttpGet]
     2         public ActionResult<IEnumerable<string>> Get()
     3         {
     4             var cer = HttpContext.Connection.ClientCertificate;  
     5             //证书为空,返回BadRequest
     6             if (cer == null)
     7             {
     8                 return BadRequest();
     9             }
    10             else
    11             {
    12                 return new string[] { "value1", "value2" };
    13             }
    14         }

    创建客户应用,.net core的控制台项目,把client.pfx添加到项目中,并设置属性为“始终复制”,然后代码如下

     1         static void Main(string[] args)
     2         {
     3             Console.WriteLine("enter start");
     4             while (true)
     5             {
     6                 try
     7                 {
     8                     Console.WriteLine("1、Https   2、Http");
     9                     switch (Console.ReadLine())
    10                     {
    11                         case "1":
    12                             HttpsMethod();
    13                             break;
    14                         case "2":
    15                             HttpMethod();
    16                             break;
    17                     }
    18                     void HttpsMethod()
    19                     {
    20                         var handler = new HttpClientHandler();
    21                         handler.ClientCertificateOptions = ClientCertificateOption.Manual;
    22                         handler.SslProtocols = SslProtocols.Tls12 | SslProtocols.Tls | SslProtocols.None | SslProtocols.Tls11;
    23                         try
    24                         {
    25                            //加载客户端证书
    26                             var crt = new X509Certificate2(Directory.GetCurrentDirectory() + "/client.pfx", "cccccc"); 
    27                             handler.ClientCertificates.Add(crt);
    28                         }
    29                         catch (Exception e)
    30                         {
    31                             Console.WriteLine(e.Message);
    32                         }
    33                         //用chain.Build验证服务器证书
    34                         handler.ServerCertificateCustomValidationCallback = (message, cer, chain, errors) =>
    35                         {                           
    36                             return  chain.Build(cer);                           
    37                         };
    38                         var client = new HttpClient(handler);
    39                         var url = "https://192.168.252.41 /api/values";
    40                         var response = client.GetAsync(url).Result;
    41                         Console.WriteLine(response.IsSuccessStatusCode);
    42                         var back = response.Content.ReadAsStringAsync().Result;
    43                         Console.WriteLine(back);
    44                     }
    45                     void HttpMethod()
    46                     {
    47                         var client = new HttpClient();
    48                         var url = "http://192.168.252.41/api/values";
    49                         var response = client.GetAsync(url).Result;
    50                         Console.WriteLine(response.IsSuccessStatusCode);
    51                         var back = response.Content.ReadAsStringAsync().Result;
    52                         Console.WriteLine(back);
    53                     }
    54                 }
    55                 catch (Exception exc)
    56                 {
    57                     Console.WriteLine(exc.InnerException?.InnerException?.Message);
    58                 }
    59             }
    60         }

    结果如下图:

     

    代码:https://github.com/axzxs2001/Asp.NetCoreExperiment/tree/master/Asp.NetCoreExperiment/Certificate

  • 相关阅读:
    django 省 市 区 联动
    ACM/ICPC 之 Dinic算法(POJ2112)
    ACM/ICPC 之 网络流入门-EK算法(参考模板)(POJ1273)
    ACM/ICPC 之 网络流入门-Ford Fulkerson与SAP算法(POJ1149-POJ1273)
    ACM/ICPC 之 DFS求解欧拉通路路径(POJ2337)
    ACM/ICPC 之 DFS求解欧拉回路+打表(POJ1392)
    ACM/ICPC 之 暴力打表(求解欧拉回路)-编码(POJ1780)
    ACM/ICPC 之 昂贵的聘礼-最短路解法(POJ1062)
    ACM/ICPC 之 SPFA-兑换货币(POJ1860)
    ACM/ICPC 之 欧拉回路两道(POJ1300-POJ1386)
  • 原文地址:https://www.cnblogs.com/axzxs2001/p/10070562.html
Copyright © 2011-2022 走看看