SSL
一直沒有真正研究過SSL,不知道下面的理解是否正確。
SSL是Secure Sockets Layer的縮寫,它用來保護伺服器和客戶端之前的通訊。它是基於信任+加密的概念。
在介紹SSL的原理之前,首先介紹一下加密(Encryption)的概念。
在很多的應用/API裡,最常見的一種加密的方式是對稱加密(Symmetric Encryption)。
對稱加密的原理是這樣的:比如說甲方想要傳送一些資料給某個呼叫者(乙方),乙方可能在某個程式或客戶端伺服器裡,或者是跨越網路的。總之是兩方通訊。而甲方傳送加密的資料需要一些加密的方法,這個加密方法雙方必須都知道(例如AES),此外還需要一個secret,它是一個任意的字串,加密方法需要使用secret來進行加密。使用這樣的加密方法把資料加密,然後加密的資料就會被髮給乙方。乙方在接受這個加密後的資料之後,需要同樣的加密方法和同樣的secret來進行解密。所以對稱加密的弱點也就在這,這個secret需要在雙方共享。
而對於SSL來說,它還可以使用第二種加密方式:非對稱加密(Asymetric Encryption)。
非對稱加密的原理是這樣的,它也需要加密方法來對資料進行加密,但加密的時候使用的是public key
,這個public key是從乙方那裡獲得的;它實際就是一個secret,但是這個secret並沒有被保護,所以乙方並不擔心甲方或其他方使用它來進行解密,因為public key不可以用來解密,它只能用來進行加密。而當乙方接收到加密資料之後,它使用private key來進行解密,這個private key是保密的,別人不知道的,這樣乙方就可以得到解密後的資料。
所以非對稱加密的優勢還是很明顯的。
SSL使用這兩種加密方式。
當客戶端和(Web)伺服器使用SSL進行通訊前會有一個SSL握手的操作,使用者是不會察覺這個動作的,它發生在真正呼叫API之前。
當客戶端開始請求(https)後,伺服器首先返回的是證書。
證書裡面包含了很多的資訊,這些資訊首先就可以用來對證書本身進行信任確認。證書裡包含了一些承諾:包括這個證書來自受信任的源。例如你使用SSL請求Microsoft.com,那麼返回的證書就會對你承諾:“這個伺服器是被微軟所擁有的”等。證書還會包含著“誰可以保證這些資訊的真實性”的資訊。這裡還有一個證書頒發機構(Certificate Authority,CA)的列表,這些機構是我不得不信任的,證書頒發機構可以保證這些資訊等真實性。這裡的證書就是由這些機構來簽發的。通常瀏覽器都會載入這些知名證書頒發機構的根證書。這些機構維護著一個所有已簽名證書的列表和已經被吊銷的證書的列表。未簽名的證書是不安全的,已簽名的證書是不可以被修改的。自己簽名的證書叫自簽名證書。所有的根證書頒發機構的證書都是自簽名的。
伺服器返回證書的同時還返回了一個public key,瀏覽器根據信任的CA來檢查證書是否仍然有效並且和該網站仍然關聯。
如果瀏覽器最終信任了這個證書,那麼它會使用這個public key來生成加密一個隨機的對稱加密key並把它使用加密的URL和HTTP資料一同送回到伺服器。
伺服器通過它的private key來對這個對稱的加密key進行解密,隨後用解密出來的對稱key來解密URL和HTTP資料。然後伺服器會使用這個對稱加密key發出一個加密確認,接下來加密的對話就可以開始了,後續的通訊都是使用這個對稱key。
那麼為什麼整個通訊不都使用非對稱加密呢?因為它比較消耗資源。所以非對稱加密只用在SSL握手階段來建立一個後續對話的對稱加密key,後續的通訊都是使用這個對稱key來加密傳輸的資料。
在ASP.NET Core中啟用HTTPS
HTTPS (也叫做 HTTP over TLS, HTTP over SSL, and HTTP Secure),它的傳輸協議使用TLS(SSL)加密。
下面都是官方文件的內容。
官方建議ASP.NET Core應用使用HTTPS重定向中介軟體來把所有的HTTP請求都重定向到HTTPS上。
而實際上,ASP.NET Core 2.1的webapi模版裡已經這樣做了:
此外還可以在ConfigureServices方法裡配置該中介軟體:
這裡把返回到狀態碼設為307,這其實是預設值。而生產環境應該呼叫 UseHsts方法。
然後把Https的埠設定為5001,預設值是443。
注意:需要同時監聽http和https的埠。
執行程式,使用POSTMAN發出一個GET請求到ValuesController:
沒有返回任何響應,這是因為POSTMAN到設定問題。請按照下圖修改POSTMAN到配置:
把SSL certificate verification一項設定成 OFF。
然後再傳送GET請求就OK了:
這裡面有一個重定向到過程,我們改一下POSTMAN到設定來看一下這個過程:
把Automatically follow redirects改為OFF。
然後傳送HTTP的請求:
它返回的body是空的,Header裡面有重定向的地址,狀態碼是307,也就是我之前配置的。
然後我再傳送請求到Header裡Location到這個地址就會得到想要到結果,我就不貼圖了。