https
背景
由于 apple 宣布蘋果App于2017年1月1日(已宣布延遲)將啟用App Transport Security安全功能,即強制App通過HTTPS連接網絡服務,這使得大小公司的程序員加班加點切換http到https.
蘋果為啥為啥非要切換https,難道是折騰程序員好玩?其實早在2015年9月的WWDC15上,蘋果公司就提出了ATS(App Transport Security),所謂的ATS是一種新型加密技術-Forward Secrecy,要求應用與后臺通訊必須使用最新的TLS1.2版本Https協議,以及所有Apple Store中的App必須使用SHA256算法的SSL/TLS證書。蘋果提出這個戰略的原因是:隨著全球互聯網安全意識的進一步覺醒,越來越多的公司意識到網絡信息安全的重要性,只有絕對的加密才能保證在線交易和商務活動的安全進行。互聯網無疑是個人信息和隱私泄露最頻繁的場合,各種以竊取信息為方式而展開的網絡犯罪是互聯網發展所面臨的最大挑戰。在這樣一個大環境下,蘋果公司首先做出應對,強制所有App在2017年1月1日前使用HTTPS加密。所以蘋果在“擁抱變化”上還是處理最前沿的,不得不佩服蘋果的魄力。
那我們就來看一下https到底是怎么樣來保證安全的。
https 原理
https安全性
https 保證了三方面的安全性:
- 1)加密數據以防止數據中途被竊取
- 2)認證用戶和服務器,確保數據發送到正確的客戶機和服務器
- 3)維護數據的完整性,確保數據在傳輸過程中不被改變。
我們將圍繞這三個點來解釋https 的實現原理。
http 與https的差別
想了解https的安全性,首先得了解一下http的不安全性,怎么樣也得讓http死得明白!
假定一個場景,我們在登錄頁面,用戶輸入賬號密碼進行登錄
用戶登錄->各種路由、代理服務器等->實際授權服務器
我們的賬號密碼等信息需要經過很長的路徑才能到達目標服務器,在到達授權服務器前,賬號和密碼是光著身子的,任何中間服務器想看幾眼都可以。如果你說那我們不可以通過js在前端對賬號密碼加密嗎?當然可以,但無非像黃帝的新裝,中間代理服務器仍然可以拍一張裸照,去欺騙授權服務器。
https 就是安全版的http,在http的基礎上加了一個TLS/SSL(以下統稱SSL,習慣了,至于發展過程詳見),如下圖.
通俗的講,TLS、SSL其實是類似的東西,SSL是個加密套件,負責對HTTP的數據進行加密。TLS是SSL的升級版。現在提到HTTPS,加密套件基本指的是TLS。原先是應用層將數據直接給到TCP進行傳輸,現在改成應用層將數據給到TLS/SSL,將數據加密后,再給到TCP進行傳輸。
所以下述場景變成了這個樣子:
用戶登錄->加密(穿衣服)-> 各種路由、代理服務器等-> 解密(脫衣服)->實際授權服務器
所以你的信息在傳輸的過程中就再也不用裸奔了,而且想脫都脫不掉,因為衣服上有把鎖,只有服務器的私鑰才能打開。
所以http和https最重要的區別就是TLS/SSL,https實際上就是在應用層(HTTP) 和傳輸層(TCP)之間加了一層TSL/SSL
https的握手和加密過程
整個過程分為以下幾個步驟:
- 驗證證書有效性(是否被更改,是否合法)
- 握手生成會話密鑰
- 利用會話密鑰進行內容傳輸
下面我們來看一下整個流程
1 客戶端發出請求(ClientHello)
客戶端(通常是瀏覽器)先向服務器發出加密通信的請求,這被叫做ClientHello請求。
在這一步,客戶端主要向服務器提供以下信息。
- (1) 支持的協議版本,比如TLS 1.0版。
- (2) 一個客戶端生成的隨機數,稍后用于生成”對話密鑰”。
- (3) 支持的加密方法,比如RSA公鑰加密。
- (4) 支持的壓縮方法。
這里需要注意的是,客戶端發送的信息之中不包括服務器的域名。也就是說,理論上服務器只能包含一個網站,否則會分不清應該向客戶端提供哪一個網站的數字證書。這就是為什么通常一臺服務器只能有一張數字證書的原因。
對于虛擬主機的用戶來說,這當然很不方便。2006年,TLS協議加入了一個Server Name Indication擴展,允許客戶端向服務器提供它所請求的域名。
2/3 服務器回應(SeverHello)
服務器收到客戶端請求后,向客戶端發出回應,這叫做SeverHello。服務器的回應包含以下內容。
- (1) 確認使用的加密通信協議版本,比如TLS 1.0版本。如果瀏覽器與服務器支持的版本不一致,服務器關閉加密通信。
- (2) 一個服務器生成的隨機數,稍后用于生成”對話密鑰”。
- (3) 確認使用的加密方法,比如RSA公鑰加密。
- (4) 服務器證書。
除了上面這些信息,如果服務器需要確認客戶端的身份,就會再包含一項請求,要求客戶端提供”客戶端證書”。比如,金融機構往往只允許認證客戶連入自己的網絡,就會向正式客戶提供USB密鑰,里面就包含了一張客戶端證書。
4 客戶端驗證證書
客戶端收到服務器回應以后,首先驗證服務器證書。
如果證書不是可信機構頒布、或者證書中的域名與實際域名不一致、或者證書已經過期,就會向訪問者顯示一個警告,由其選擇是否還要繼續通信。
驗證證書主要根據服務端發過來的證書名稱,在本地尋找其低級證書,并一級一級直到根證書,驗證各級證書的合法性。證書的詳情內容,請見本文附錄
5 客戶端回應
如果證書沒有問題,客戶端就會從證書中取出服務器的公鑰。然后,向服務器發送下面三項信息。
- (1) 一個隨機數。該隨機數用服務器公鑰加密,防止被竊聽。
- (2) 編碼改變通知,表示隨后的信息都將用雙方商定的加密方法和密鑰發送。
- (3) 客戶端握手結束通知,表示客戶端的握手階段已經結束。這一項同時也是前面發送的所有內容的hash值,用來供服務器校驗。
6 生成會話密鑰
上面第一項的隨機數,是整個握手階段出現的第三個隨機數,又稱”pre-master key”。有了它以后,客戶端和服務器就同時有了三個隨機數,接著雙方就用事先商定的加密方法,各自生成本次會話所用的同一把”會話密鑰”。
至于為什么一定要用三個隨機數,來生成”會話密鑰”,dog250解釋得很好:
“不管是客戶端還是服務器,都需要隨機數,這樣生成的密鑰才不會每次都一樣。由于SSL協議中證書是靜態的,因此十分有必要引入一種隨機因素來保證協商出來的密鑰的隨機性。
對于RSA密鑰交換算法來說,pre-master-key本身就是一個隨機數,再加上hello消息中的隨機,三個隨機數通過一個密鑰導出器最終導出一個對稱密鑰。
pre master的存在在于SSL協議不信任每個主機都能產生完全隨機的隨機數,如果隨機數不隨機,那么pre master secret就有可能被猜出來,那么僅適用pre master secret作為密鑰就不合適了,因此必須引入新的隨機因素,那么客戶端和服務器加上pre master secret三個隨機數一同生成的密鑰就不容易被猜出了,一個偽隨機可能完全不隨機,可是是三個偽隨機就十分接近隨機了,每增加一個自由度,隨機性增加的可不是一。”
服務器收到客戶端的第三個隨機數pre-master key之后,計算生成本次會話所用的”會話密鑰”。
此外,如果前一步,服務器要求客戶端證書,客戶端會在這一步發送證書及相關信息。
7 服務器的最后回應
服務端生成”會話密鑰”后,向客戶端最后發送下面信息。
- (1)編碼改變通知,表示隨后的信息都將用雙方商定的加密方法和密鑰發送。
- (2)服務器握手結束通知,表示服務器的握手階段已經結束。這一項同時也是前面發送的所有內容的hash值,用來供客戶端校驗。
至此,整個握手階段全部結束。接下來,客戶端與服務器進入加密通信,就完全是使用普通的HTTP協議,只不過用”會話密鑰”加密內容。
2.3 https 的優勢
https有三種優勢:
- 1)加密數據以防止數據中途被竊取
- 2)認證用戶和服務器,確保數據發送到正確的客戶機和服務器
- 3)維護數據的完整性,確保數據在傳輸過程中不被改變。
通過了解TSL/SSL的工作原理,我們知道:
通訊過程中的hash 生成的摘要,保證了數據的完整性;
握手的非對稱加密和傳輸過程中的對稱加密保證了數據的私密性
客戶端驗證證書以及“金融系統中USB證書”保證了客戶端和服務端的真實性。
2.4 如何使用代理(charles)
charles抓包方式
我們知道從https的整個原理來可以知道,客戶端和服務端進行通信的過程,客戶端能拿到數據,代理也一定能拿到,包括公共密鑰、證書、算法等。但代理無法獲取服務器的私鑰,所以無法獲取5/6/7過程中的會話密鑰,也就無法得到數據傳輸過程中明文,所以默認情況下,charles是無法抓https的,或者說抓到的也是亂碼。
那如何讓charles抓包并獲取明文?也就是得讓charles獲取私鑰,獲取服務器的是不可能的,那只能在通信過程中使用charles自己的證書,并在通信的過程中主動為請求的域名發放證書。示例流程如下:
從上面可以看出,一旦信任代理的證書,代理在中間就做一個轉換的角色,即擔任客戶端的服務器,又擔任服務端的客戶端,在中間傳輸的過程中做了加解密轉換。也就是說一旦信任代理,代理就可以干任何事。
2.5 https 的確陷
其實我們在上面已經談到了,一旦信任CA,CA發放的證書都將成為可信的,CA發放的機構不一定是安全的,特別是自制的證書,一旦信任,在其發放證書的所有服務器上的個人信息都是裸露的狀態,要悲的是你又不知道他會用你的信息干啥。所以不要輕易信任第三方證書。
三 附錄-證書格式
- 證書版本號(Version)
版本號指明X.509證書的格式版本,現在的值可以為:
- 0: v1
- 1: v2
- 2: v3
也為將來的版本進行了預定義
- 2: v3
證書序列號(Serial Number)
序列號指定由CA分配給證書的唯一的"數字型標識符"。當證書被取消時,實際上是將此證書的序列號放入由CA簽發的CRL中,
這也是序列號唯一的原因。簽名算法標識符(Signature Algorithm).
簽名算法標識用來指定由CA簽發證書時所使用的"簽名算法"。算法標識符用來指定CA簽發證書時所使用的:
- 公開密鑰算法
- hash算法
example: sha256WithRSAEncryption
須向國際知名標準組織(如ISO)注冊
- hash算法
- 簽發機構名(Issuer)
此域用來標識簽發證書的CA的X.500 DN(DN-Distinguished Name)名字。包括:
- 國家(C)
- 省市(ST)
- 地區(L)
- 組織機構(O)
- 單位部門(OU)
- 通用名(CN)
- 郵箱地址
- 有效期(Validity)
指定證書的有效期,包括:
- 證書開始生效的日期時間
- 證書失效的日期和時間
每次使用證書時,需要檢查證書是否在有效期內。
- 證書失效的日期和時間
- 證書用戶名(Subject)
指定證書持有者的X.500唯一名字。包括:
- 國家(C)
- 省市(ST)
- 地區(L)
- 組織機構(O)
- 單位部門(OU)
- 通用名(CN)
- 郵箱地址
- 證書持有者公開密鑰信息(Subject Public Key Info)
證書持有者公開密鑰信息域包含兩個重要信息:
- 證書持有者的公開密鑰的值
- 公開密鑰使用的算法標識符。此標識符包含公開密鑰算法和hash算法。
擴展項(extension)
X.509 V3證書是在v2的基礎上一標準形式或普通形式增加了擴展項,以使證書能夠附帶額外信息。標準擴展是指
由X.509 V3版本定義的對V2版本增加的具有廣泛應用前景的擴展項,任何人都可以向一些權威機構,如ISO,來
注冊一些其他擴展,如果這些擴展項應用廣泛,也許以后會成為標準擴展項。簽發者唯一標識符(Issuer Unique Identifier)
簽發者唯一標識符在第2版加入證書定義中。此域用在當同一個X.500名字用于多個認證機構時,用一比特字符串
來唯一標識簽發者的X.500名字。可選。證書持有者唯一標識符(Subject Unique Identifier)
持有證書者唯一標識符在第2版的標準中加入X.509證書定義。此域用在當同一個X.500名字用于多個證書持有者時,
用一比特字符串來唯一標識證書持有者的X.500名字。可選。簽名算法(Signature Algorithm)
證書簽發機構對證書上述內容的簽名算法
example: sha256WithRSAEncryption簽名值(Issuer's Signature)
證書簽發機構對證書上述內容的簽名值