前幾天搞go 的Grpc和http2的雙向認證。如今來搞搞。net core 裏面是如何實現的html
首先須要下載 OpenSSL http://slproweb.com/products/Win32OpenSSL.html web
運行-> certmgr.msc 如圖:我這裏有2個 一個 做爲做爲server2.pfx"一個做爲client2.pfxwindows
接下來建立asp.net core web api項目,並把server.pfx添加到項目中,並設置屬性爲「始終複製」,接着修改Program.cs下的CreateHostBuilder方法就能夠:api
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請求,在WeatherForecastController中寫以下代碼:服務器
[HttpGet] public IEnumerable<WeatherForecast> Get() { var rng = new Random(); var cer = HttpContext.Connection.ClientCertificate; //證書爲空,返回過去的時間 if (cer == null) { return Enumerable.Range(1, 5).Select(index => new WeatherForecast { Date = DateTime.Now.AddDays(-index), TemperatureC = rng.Next(-20, 55), Summary = Summaries[rng.Next(Summaries.Length)] }) .ToArray(); } return Enumerable.Range(1, 5).Select(index => new WeatherForecast { Date = DateTime.Now.AddDays(index), TemperatureC = rng.Next(-20, 55), Summary = Summaries[rng.Next(Summaries.Length)] }) .ToArray(); }
建立客戶應用,.net core的控制檯項目,把client.pfx添加到項目中,並設置屬性爲「始終複製」,而後代碼以下asp.net
static void Main(string[] args) { HttpsMethod(); } static void HttpsMethod() { ServicePointManager.ServerCertificateValidationCallback = delegate (object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors) { return true; }; var handler = new HttpClientHandler(); handler.ClientCertificateOptions = ClientCertificateOption.Manual; handler.SslProtocols = SslProtocols.Tls12 | SslProtocols.Tls | SslProtocols.None | SslProtocols.Tls11; try { //加載客戶端證書 var crt = new X509Certificate2(Directory.GetCurrentDirectory() + "/cert/client2.pfx", "123456789"); handler.ClientCertificates.Add(crt); } catch (Exception e) { Console.WriteLine(e.Message); } //用chain.Build驗證服務器證書 handler.ServerCertificateCustomValidationCallback = (message, cer, chain, errors) => { return chain.Build(cer); }; var client = new HttpClient(handler); var url = "https://localhost:5001/WeatherForecast"; var response = client.GetAsync(url).Result; Console.WriteLine(response.IsSuccessStatusCode); var back = response.Content.ReadAsStringAsync().Result; Console.WriteLine(back); }
結果以下圖:dom
關於證書的建立, 我參考了別人作法, 但仍是提示 the remote certificate is invalid according to the validation procedure., 網上說的 dotnet dev-certs https --trust 試了沒用, 還有就是安裝證書 也仍是沒用ui
證書建立:url
1、建立根證書spa
//生成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上安裝證書時,證書存儲可選擇「受信任的根證書頒發機構
2、建立服務端證書
//生成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
3、建立客戶端證書
//生成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
這個操做方法 不肯定是否好用, 網上別人成功了的, 可是我安裝後如圖:
參考: