.net core https 雙向驗證


文章來自:https://www.cnblogs.com/axzxs2001/p/10070562.html

 

關於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-Win64\bin(最好不要改路徑,否則生成證書時要改配置文件路徑)下以管理員運行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方法就可以:

 public static IHostBuilder CreateHostBuilder(string[] args) =>
            Host.CreateDefaultBuilder(args)
                .ConfigureWebHostDefaults(webBuilder =>
                {
                    webBuilder.UseKestrel(
                          options =>
                          {
                             options.Listen(IPAddress.Any, 5001, listenOptions =>
                              {
                                  var serverPath = AppDomain.CurrentDomain.BaseDirectory + "cert\\server2.pfx";
                                  var serverCertificate = new X509Certificate2(serverPath, "123456789");
                                  var httpsConnectionAdapterOptions = new HttpsConnectionAdapterOptions()
                                  {
                                      ClientCertificateMode = ClientCertificateMode.AllowCertificate,
                                      SslProtocols = SslProtocols.Tls12 | SslProtocols.Tls | SslProtocols.None | SslProtocols.Tls11,
                                     ClientCertificateValidation = (cer, chain, error) =>
                                      {
                                          return chain.Build(cer);
                                      },
                                      ServerCertificate = serverCertificate
                                      
                                  };
                                  listenOptions.UseHttps(httpsConnectionAdapterOptions);
                              });
                              
                          }).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         }
復制代碼

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM