天天看點

白話文解讀HTTPS原理, 結合.NET Core聊一聊HTTPS應用方式

       合格的web後端程式員,除搬磚技能,還必須會給各種web伺服器配置Https,本文結合ASP.NET Core部署模型聊一聊啟用Https的方式。

溫故知新

目前常見的Http請求明文傳輸,請求可能被篡改,通路的站點可能被僞造。

HTTPS是HTTP加上TLS/SSL協定建構的可進行加密傳輸、身份認證的網絡協定,主要通過數字證書、加密算法、非對稱密鑰等技術完成網際網路資料傳輸加密,實作網際網路傳輸安全保護。

HTTPS是應用層協定

注意,HTTPS是與DNS平級的應用層協定, 一個常見HTTPS請求的過程:

 由DNS解析出IP位址----->  浏覽器向伺服器ip位址發起請求----> 伺服器向浏覽器下發證書(該證書有公鑰,并綁定了域名)-----> 浏覽器驗證證書---->....

白話文解讀HTTPS原理, 結合.NET Core聊一聊HTTPS應用方式

HTTPS 流程解讀

① 傳輸密鑰是對稱密鑰,用于雙方對傳輸資料的加解密

② 怎麼在傳輸之前确立傳輸密鑰呢?

 答:針對普遍的多用戶端通路受信web伺服器的場景, 提出非對稱密鑰(公鑰下發給用戶端,私鑰存于web伺服器),雙方能互相加解密,說明中間資料(傳輸密鑰)沒被篡改。

③ 再抛出疑問,用戶端如何認定下發的公鑰是目标web伺服器的公鑰?又如何确定公鑰下發過程沒被截取篡改?

 答:追溯到握手階段的證書驗證過程,浏覽器從證書提取(證書頒發機構,證書綁定的域名,證書簽名,證書有效期),

  浏覽器先驗證證書綁定的域名是否與目标域名比對;浏覽器内置證書頒發機構認定該證書是其有效下發;通過簽名認定該證書沒被篡改。

④ 是以浏覽器内置的證書機構(根證書)的權威性相當重要, 浏覽器中毒或劣質浏覽器可能攜帶 非法的根證書。

 如果面向面試記憶Https原理,恐怕有些難度,是以個人用一種 【雞生蛋還是蛋生雞】的方式向上追溯流程, 友善大家知其然更知其是以然 

⑤ 是不是隻有CA機構才能簽發證書 ?  

 不是的,伺服器上存儲的證書和公鑰,隻要是比對的就可以下發;由浏覽器決定是否信任證書。

  是以在測試和開發階段,通常在伺服器上申請 自簽名證書,浏覽器會提示你證書無效,但是你可手動忽略,或添加到信任清單。

下面示範對ASP.NET Core程式兩種最常見部署模型強制應用HTTPS.

正常反向代理模型

白話文解讀HTTPS原理, 結合.NET Core聊一聊HTTPS應用方式

 由nginx反向代理請求到後端https://receiver.server, nginx上添加HTTPS證書, 并強制浏覽器使用 HTTPS。

worker_processes 4;
events { worker_connections 1024; }
http {
    sendfile on;
    upstream receiver_server {
        server receiver:80;
    }
    server {
        listen 80;
        listen [::]:80;
        server_name  eqid.******.com;
        return 301 https://$host$request_uri;
    }

    server {
        listen       443 ssl;
        listen       [::]:443 ssl;
        ssl          on;
        server_name  eqid.******.com;

        ssl_certificate         /conf.crt/live/******.com.crt;
        ssl_certificate_key     /conf.crt/live/******.com.key;
        location / {
            proxy_pass         http://receiver_server;
            proxy_http_version 1.1;
            proxy_set_header   Upgrade $http_upgrade;
            proxy_set_header   Connection keep-alive;
            proxy_redirect     off;
            proxy_set_header   Host $host;
            proxy_cache_bypass $http_upgrade;
            proxy_set_header   X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_set_header   X-Forwarded-Proto $scheme;
        }
    }
}      

黃色背景行顯示: nginx對http:80 請求傳回301(重定向,Moved Permanently), 要求浏覽器使用Https發起請求。

綠色背景行顯示: nginx對此次 https請求,在協商階段會下發ssl_certificate證書, 會使用 ssl_certificate_key 私鑰進行非對稱解密。

dotnet.exe自宿模型

白話文解讀HTTPS原理, 結合.NET Core聊一聊HTTPS應用方式

 Kestrel用作邊緣(面向Internet)Web伺服器, 這個部署模型不常見,但依舊存在。

我們利用 Visual Studio 2019項目模闆建構 ASP.NetCore項目--- 勾選HTTPS支援, 會預設添加Https支援;

  • app.UseHttpsRedirection()   要求浏覽器的Http請求  重定向使用 HTTPS協定
  • app.UseHsts()
HSTS(HTTP Strict Transport Protocol)的作用是強制浏覽器使用HTTPS與伺服器建立連接配接,避免原有的301重定向Https時可能發生中間人劫持
伺服器開啟HSTS的方法是,當用戶端通過HTTPS送出請求時,在伺服器傳回的超文本傳輸協定響應頭中包含Strict-Transport-Security字段。非加密傳輸時設定的HSTS字段無效。      

  它告訴浏覽器為特定的主機頭和特定的時間範圍緩存證書。

開發證書

VS模闆建構的web會使用dotnet cli 提供的開發證書在https://localhost:5001 位址接收請求。

安裝 .NET Core SDK 會将 ASP.NET Core HTTPS 開發證書安裝到本地使用者證書存儲 , 可倒騰 dotnet dev-certs https --help 指令:

dotnet dev-certs https --clean  清除證書,啟動程式會報 System.InvalidOperationException:“Unable to configure HTTPS endpoint. No server certificate was specified, and the default developer certificate could not be found or is out of date. To generate a developer certificate run 'dotnet dev-certs https'. To trust the certificate (Windows and macOS only) run 'dotnet dev-certs https --trust'.

dotnet dev-certs https -t  信任證書,會彈窗提示安裝名為localhost的根證書:

     - 否,web能正常啟動,浏覽器Https請求能獲驗證書,但會警示 ▲不安全 (浏覽器不信任localhost根證書,證書無效)

    -  是,web正常啟動,浏覽器發起的Https請求,顯示正常的顯示♎ 圖示

在Windows上,最安全方式是使用certificate store來注冊已認證的HTTPS,但是有時候希望在程式内綁定證書+私鑰, 這樣便于在不同平台上部署。

檔案證書

ASP.NET Core支援使用硬碟上檔案證書來建立Https連接配接(這在linux上很常見)。

以下代碼允許Kestrel 傳入檔案證書和私鑰,并建立Https連接配接。

public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
    WebHost.CreateDefaultBuilder(args)
        .UseKestrel(options =>
        {
            options.Listen(IPAddress.Loopback, 5000);
            options.Listen(IPAddress.Loopback, 5001, listenOptions =>
            {
                listenOptions.UseHttps("certificate.pfx", "topsecret");
            });
        })
        .UseStartup<Startup>();      

務必確定不要将私鑰存儲在配置檔案中:在開發模式,可使用 user secrets 存儲此類密鑰;在生産模式,可考慮Azure Key Vault或環境變量。

完整密鑰分離請參考: https://www.cnblogs.com/JulianHuang/p/11462607.html

程式設計允許HttpClient發起不安全的請求

有時候你會使用HttpClient等用戶端去請求 受信HTTPS站點, 但是因為某些原因(自簽名證書,證書過期), 下發的證書無效 (這個時候浏覽器會提示,你可選擇忽略,或者手動添加到受信清單繼續請求),

但是程式設計方式的HttpClinet 會立刻終止請求。

給栗子:

使用預設的HttpClient BaseAddress=https://127.0.0.1:5001,通路ASP.NET Core 預設站點https://localhost:5001,  會出現:

白話文解讀HTTPS原理, 結合.NET Core聊一聊HTTPS應用方式

這個時候你可考慮重寫HttpClient ServerCertificateCustomValidationCallback屬性 忽略無效證書報錯。

[Route("test")]
        public async Task<string> Get()
        {
            var client = new HttpClient(new HttpClientHandler()
            {
                AllowAutoRedirect = true,
                ServerCertificateCustomValidationCallback = (x1, x2, x3, x4) => true
            });
            var resp = await  client.GetAsync("https://127.0.0.1:5001");
            return await resp.Content.ReadAsStringAsync();
        }      

總結 

希望本文有助于您大緻了解 HTTPS的協定原理,常見的HTTPS的應用方式,

結合.NETCore 說明開發證書 和 檔案證書的使用方式, 最後指出允許HttpClient發起不安全請求的方式。

本文來自部落格園,作者:{有态度的馬甲},轉載請注明原文連結:https://www.cnblogs.com/JulianHuang/p/11858800.html

歡迎關注我的原創技術、職場公衆号, 加好友談天說地,一起進化

白話文解讀HTTPS原理, 結合.NET Core聊一聊HTTPS應用方式

繼續閱讀