服务端和客户端证书各种组合下对访问者(浏览器/中间人)的影响
今天本來想研究下nginx下如果獲取SSL指紋,但是環(huán)境沒有裝成功
就嘗試了下如果不用nginx直接在服務端拿到SSL指紋,
沒想到從創(chuàng)建自簽名證書到如何開啟證書,
以及服務端證書和客戶端證書各種組合校驗的測試就花了我很長時間。
(注意自簽名證書用Rsa,我用Ecc的在asp5.0好像不支持,這里耗了我比較長時間)
所以SSL指紋就下一次在研究吧,有這方面經驗的朋友歡迎加我微信交流(文末)!
本文介紹了服務端證書和客戶端證書各種組合下,對于訪問者(瀏覽器/中間人)的影響
本文代碼基于aspnet5.0,其他語言實現文末有外鏈可參考
1. 開啟服務端SSL
public static IHostBuilder CreateHostBuilder(string[] args) =>Host.CreateDefaultBuilder(args).ConfigureWebHostDefaults(webBuilder =>{webBuilder.UseKestrel(options =>{options.ListenLocalhost(5002, listenOption =>{//設置證書var httpsOptions = new HttpsConnectionAdapterOptions();var serverCert = new X509Certificate2("server.pfx", "1234");httpsOptions.ServerCertificate = serverCert;listenOption.UseHttps(httpsOptions);});});webBuilder.UseStartup<Startup>();});server.pfx是自己創(chuàng)建的證書,需要加到根信任中心
瀏覽器訪問https沒問題
中間人抓包沒問題
客戶端HttpClient訪問沒問題
2. 開啟客戶端證書驗證
public static IHostBuilder CreateHostBuilder(string[] args) => Host.CreateDefaultBuilder(args).ConfigureWebHostDefaults(webBuilder =>{webBuilder.UseKestrel(options =>{options.ListenLocalhost(5002, listenOption =>{//設置證書var httpsOptions = new HttpsConnectionAdapterOptions();//設置需要驗證客戶端正常開始httpsOptions.ClientCertificateMode = ClientCertificateMode.RequireCertificate;//設置需要驗證客戶端正常結束var serverCert = new X509Certificate2("server.pfx", "1234");httpsOptions.ServerCertificate = serverCert;listenOption.UseHttps(httpsOptions);});});webBuilder.UseStartup<Startup>();});只需要加一句就搞定
但是注意 如果開啟了客戶端證書驗證。瀏覽器就無法訪問了。
中間人攻擊如果沒有證書的話 也無法完成!
瀏覽器無法訪問
中間人無證書無法抓包
客戶端HttpClient得配置證書才能訪問(下面)
3. 客戶端用HttpClient加證書可以訪問成功
private static async Task<string> GetApiDataAsync() {try{//注意哈 這里要和服務端用的證書一樣才行var cert = new X509Certificate2("server.pfx", "1234");var handler = new HttpClientHandler();handler.ClientCertificates.Add(cert);var client = new HttpClient(handler);var request = new HttpRequestMessage(){RequestUri = new Uri("https://localhost:5002/WeatherForecast"),Method = HttpMethod.Get,};var response = await client.SendAsync(request);if (response.IsSuccessStatusCode){var responseContent = await response.Content.ReadAsStringAsync();return responseContent;}throw new ApplicationException($"Status code: {response.StatusCode}, Error: {response.ReasonPhrase}");}catch (Exception e){throw new ApplicationException($"Exception {e}");} }4. 服務端開啟客戶端證書校驗
public static IHostBuilder CreateHostBuilder(string[] args) => Host.CreateDefaultBuilder(args).ConfigureWebHostDefaults(webBuilder =>{webBuilder.UseKestrel(options =>{options.ListenLocalhost(5002, listenOption =>{//設置證書var httpsOptions = new HttpsConnectionAdapterOptions();//設置需要驗證客戶端正常開始httpsOptions.ClientCertificateMode = ClientCertificateMode.RequireCertificate;//設置需要驗證客戶端正常結束//設置服務端驗證客戶端 開啟SSL Pinning starthttpsOptions.CheckCertificateRevocation = true;httpsOptions.ClientCertificateValidation +=(certificate2, chain, arg3) =>{//return true;//this is where we verify the thumbprint of a connected client matches the thumbprint we expect//NOTE: this is just a simple example of verifying a client cert.// 2A39D43A8FE2CAE54542C768F61AE79097FAB6F5 這個是我那個證書的 測試的話需要換下return certificate2.Thumbprint.Equals("2A39D43A8FE2CAE54542C768F61AE79097FAB6F5",StringComparison.InvariantCultureIgnoreCase);}; //設置服務端驗證客戶端 開啟SSL Pinning endvar serverCert = new X509Certificate2("server.pfx", "1234");httpsOptions.ServerCertificate = serverCert;listenOption.UseHttps(httpsOptions);});});webBuilder.UseStartup<Startup>();});注意:服務端開啟驗證的前提是需要客戶端傳證書
相比上面一步,更加保證了客戶端傳的證書的安全性。
而且只要約束了客戶端傳證書,中間人抓https的包如果拿不到證書是無法抓的!!
瀏覽器無法訪問
中間人無證書無法抓包
客戶端HttpClient得配置證書才能訪問(同上)
5. 客戶端開啟SSL Pinning
不需要客戶端傳證書(不需要服務端強制開啟客戶端傳證書)
只在客戶端驗證服務端證書。
客戶端HttpClient訪問增加開啟 SSL Pinning
var handler = new HttpClientHandler(); var client = new HttpClient(handler); //增加開啟 SSL Pinning handler.ServerCertificateCustomValidationCallback = (request, cert, chain, errors) => {//2A39D43A8FE2CAE54542C768F61AE79097FAB6F5 這個是我那個證書的 測試的話需要換下return cert.Thumbprint.Equals("2A39D43A8FE2CAE54542C768F61AE79097FAB6F5",StringComparison.CurrentCultureIgnoreCase); };var request = new HttpRequestMessage() {RequestUri = new Uri("https://localhost:5002/WeatherForecast"),Method = HttpMethod.Get, };var response = await client.SendAsync(request);試下對中間人攻擊有沒有效果
開啟并設置Fiddler代理
handler.Proxy = new WebProxy("127.0.0.1:8888");如上圖,啟動中間人攻擊后的服務端證書簽名變了
瀏覽器可訪問
中間人無證書情況無法抓包
綜上
在客戶端啟動SSL pinning 最簡單,成本最小,其他語言都有比較簡單的實現
上面演示的證書鏈只有一條,驗證的時候也可以對整個證書鏈遍歷,每個都驗證最為穩(wěn)妥!
不過不能以為客戶端開啟了SSL Pinning就安全了,因為客戶端有Hook(xpose,frida).
SSL指紋有感興趣的可以加我交流,備注下ssl。
總結
以上是生活随笔為你收集整理的服务端和客户端证书各种组合下对访问者(浏览器/中间人)的影响的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 构建属于你自己的dapr服务发现
- 下一篇: C#序列化与反序列化详解