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


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

溫故知新

目前常見的Http請求明文傳輸,請求可能被篡改,訪問的站點可能被偽造。

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

HTTPS是應用層協議

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

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

HTTPS 流程解讀

① 傳輸密鑰是對稱密鑰,用於雙方對傳輸數據的加解密

② 怎么在傳輸之前確立傳輸密鑰呢?

 答:針對普遍的多客戶端訪問受信web服務器的場景, 提出非對稱密鑰(公鑰下發給客戶端,私鑰存於web服務器),雙方能互相加解密,說明中間數據(傳輸密鑰)沒被篡改。

③ 再拋出疑問,客戶端如何認定下發的公鑰是目標web服務器的公鑰?又如何確定公鑰下發過程沒被截取篡改?

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

  瀏覽器先驗證證書綁定的域名是否與目標域名匹配;瀏覽器內置證書頒發機構認定該證書是其有效下發;通過簽名認定該證書沒被篡改。

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

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

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

 不是的,服務器上存儲的證書和公鑰,只要是匹配的就可以下發;由瀏覽器決定是否信任證書。

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

 

下面演示對ASP.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自宿模型

 

 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 地址接收請求。

關於開發證書, 可倒騰 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,  會出現:

這個時候你可考慮重寫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發起不安全請求的方式。

 


免責聲明!

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



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