HTTPS通訊原理剖析
一、基本概念
1、公鑰密碼體制(public-key cryptography)
公鑰密碼體制分為三個部分,公鑰、私鑰、加密解密演算法,它的加密解密過程如下:
- 加密:通過加密演算法和公鑰對內容(或者說明文)進行加密,得到密文。加密過程需要用到公鑰。
- 解密:通過解密演算法和私鑰對密文進行解密,得到明文。解密過程需要用到解密演算法和私鑰。注意,由公鑰加密的內容,只能由私鑰進行解密,也就是說,由公鑰加密的內容,如果不知道私鑰,是無法解密的。
公鑰密碼體制的公鑰和演算法都是公開的(這是為什麼叫公鑰密碼體制的原因),私鑰是保密的。大家都以使用公鑰進行加密,但是隻有私鑰的持有者才能解密。在實際的使用中,有需要的人會生成一對公鑰和私鑰,把公鑰釋出出去給別人使用,自己保留私鑰。
2、對稱加密演算法(symmetric key algorithms)
在對稱加密演算法中,加密使用的金鑰和解密使用的金鑰是相同的。也就是說,加密和解密都是使用的同一個金鑰。因此對稱加密演算法要保證安全性的話,金鑰要做好保密,只能讓使用的人知道,不能對外公開。這個和上面的公鑰密碼體制有所不同,公鑰密碼體制中加密是用公鑰,解密使用私鑰,而對稱加密演算法中,加密和解密都是使用同一個金鑰,不區分公鑰和私鑰。
3、非對稱加密演算法(asymmetric key algorithms)
在非對稱加密演算法中,加密使用的金鑰和解密使用的金鑰是不相同的。前面所說的公鑰密碼體制就是一種非對稱加密演算法,他的公鑰和是私鑰是不能相同的,也就是說加密使用的金鑰和解密使用的金鑰不同,因此它是一個非對稱加密演算法。
4、RSA簡介
RSA密碼體制是一種公鑰密碼體制,公鑰公開,私鑰保密,它的加密解密演算法是公開的。 由公鑰加密的內容可以並且只能由私鑰進行解密,並且由私鑰加密的內容可以並且只能由公鑰進行解密。也就是說,RSA的這一對公鑰、私鑰都可以用來加密和解密,並且一方加密的內容可以由並且只能由對方進行解密。
5、簽名和加密
我們說加密,是指對某個內容加密,加密後的內容還可以通過解密進行還原。 比如我們把一封郵件進行加密,加密後的內容在網路上進行傳輸,接收者在收到後,通過解密可以還原郵件的真實內容。
這裡主要解釋一下簽名,簽名就是在資訊的後面再加上一段內容,可以證明資訊沒有被修改過,怎麼樣可以達到這個效果呢?一般是對資訊做一個hash計算得到一個hash值(hash不可逆)。在把資訊傳送出去時,把這個hash值加密後做為一個簽名和資訊一起發出去。 接收方在收到資訊後,會重新計算資訊的hash值,並和資訊所附帶的hash值(解密後)進行對比,如果一致,就說明資訊的內容沒有被修改過,因為這裡hash計算可以保證不同的內容一定會得到不同的hash值,所以只要內容一被修改,根據資訊內容計算的hash值就會變化。當然,不懷好意的人也可以修改資訊內容的同時也修改hash值,從而讓它們可以相匹配,為了防止這種情況,hash值一般都會加密後(也就是簽名)再和資訊一起傳送,以保證這個hash值不被修改。至於如何讓別人可以解密這個簽名,這個過程涉及到數字證書等概念,我們後面在說到數字證書時再詳細說明,這裡您先只需先理解簽名的這個概念。
二、加密通訊演練
假設“伺服器”和“客戶”要在網路上通訊,並且他們打算使用RSA來對通訊進行加密以保證談話內容的安全。由於是使用RSA這種公鑰密碼體制,“伺服器”需要對外發布公鑰(演算法不需要公佈,RSA的演算法大家都知道),自己留著私鑰。“客戶”通過某些途徑拿到了“伺服器”釋出的公鑰,客戶並不知道私鑰。“客戶”具體是通過什麼途徑獲取公鑰的,我們後面再來說明,下面看一下雙方如何進行保密的通訊:
1、場景一
如上圖所示,如果有人截獲客戶與伺服器的資訊,冒充自己是伺服器,將會出現如下圖所示情況。
因此“客戶”在接到訊息後,並不能肯定這個訊息就是由“伺服器”發出的,某些“黑客”也可以冒充“伺服器”發出這個訊息。如何確定資訊是由“伺服器”發過來的呢?有一個解決方法,因為只有伺服器有私鑰,所以如果只要能夠確認對方有私鑰,那麼對方就是“伺服器”。因此通訊過程可以改進為如下:
2、場景二
注意:{} 表示RSA加密後的內容,[ | ]表用什麼金鑰和演算法進行加密,後面的示例中都用這種表示方式,例如上面的 {XXX}[私鑰|RSA] 就表示用私鑰對“Hello, I’m server”進行加密後的結果。
為了向“客戶”證明自己是“伺服器”, “伺服器”把一個字串用自己的私鑰加密,把明文和加密後的密文一起發給“客戶”。對於這裡的例子來說,就是把字串 “Hello, I’m server”和這個字串用私鑰加密後的內容 {XXX}[私鑰|RSA] 發給客戶。
“客戶”收到資訊後,用自己持有的公鑰解密密文,和明文進行對比,如果一致,說明資訊的確是由伺服器發過來的。也就是說“客戶”把 {XXX}[私鑰|RSA] 這個內容用公鑰進行解密,然後和“Hello, I’m server”對比。因為由“伺服器”用私鑰加密後的內容,由並且只能由公鑰進行解密,私鑰只有“伺服器”持有,所以如果解密出來的內容是能夠對得上的,那說明資訊一定是從“伺服器”發過來的。
假設“黑客”想冒充“伺服器”,會發生如下會話:
在上述第四步 {###}[***|RSA],這裡黑客無法冒充,因為他不知道私鑰,無法用私鑰加密某個字串後傳送給客戶去驗證。
由於“黑客”沒有“伺服器”的私鑰,因此它傳送過去的內容,“客戶”是無法通過伺服器的公鑰解密的,因此可以認定對方是個冒牌貨!
到這裡為止,“客戶”就可以確認“伺服器”的身份了,可以放心和“伺服器”進行通訊,但是這裡有一個問題,通訊的內容在網路上還是無法保密。為什麼無法保密呢?通訊過程不是可以用公鑰、私鑰加密嗎?其實用RSA的私鑰和公鑰是不行的,我們來具體分析下過程,看下面的場景:
3、場景三
注意上面的的資訊 {money=100}[私鑰],這個是“伺服器”用私鑰加密後的內容,但是我們之前說了,公鑰是釋出出去的,因此所有的人都知道公鑰,所以除了“客戶”,其它的人也可以用公鑰對{money=100}[私鑰]進行解密。所以如果“伺服器”用私鑰加密發給“客戶”,這個資訊是無法保密的,因為只要有公鑰就可以解密這內容。然而“伺服器”也不能用公鑰對傳送的內容進行加密,因為“客戶”沒有私鑰,傳送個“客戶”也解密不了。
這樣問題就又來了,那又如何解決呢?在實際的應用過程,一般是通過引入對稱加密來解決這個問題,看下面的場景:
4、場景四
在上面的通訊過程中,“客戶”在確認了“伺服器”的身份後,“客戶”自己選擇一個對稱加密演算法和一個金鑰,把這個對稱加密演算法和金鑰一起用公鑰加密後傳送給“伺服器”。注意,由於對稱加密演算法和金鑰是用公鑰加密的,就算這個加密後的內容被“黑客”截獲了,由於沒有私鑰,“黑客”也無從知道對稱加密演算法和金鑰的內容。
由於是用公鑰加密的,只有私鑰能夠解密,這樣就可以保證只有伺服器可以知道對稱加密演算法和金鑰,而其它人不可能知道(這個對稱加密演算法和金鑰是“客戶”自己選擇的,所以“客戶”自己當然知道如何解密加密)。這樣“伺服器”和“客戶”就可以用對稱加密演算法和金鑰來加密通訊的內容了。
總結一下,RSA加密演算法在這個通訊過程中所起到的作用主要有兩個:
- 因為私鑰只有“伺服器”擁有,因此“客戶”可以通過判斷對方是否有私鑰來判斷對方是否是“伺服器”。
- 客戶端通過RSA的掩護,安全的和伺服器商量好一個對稱加密演算法和金鑰來保證後面通訊過程內容的安全。
但是這裡還留有一個問題,在最開始我們就說過,“伺服器”要對外發布公鑰,那“伺服器”如何把公鑰傳送給“客戶”呢?我們第一反應可能會想到以下的兩個方法:
a)把公鑰放到網際網路的某個地方的一個下載地址,事先給“客戶”去下載。
b)每次和“客戶”開始通訊時,“伺服器”把公鑰發給“客戶”。
但是這個兩個方法都有一定的問題,
對於a)方法,“客戶”無法確定這個下載地址是不是“伺服器”釋出的,你憑什麼就相信這個地址下載的東西就是“伺服器”釋出的而不是別人偽造的呢,萬一下載到一個假的怎麼辦?另外要所有的“客戶”都在通訊前事先去下載公鑰也很不現實。
對於b)方法,也有問題,因為任何人都可以自己生成一對公鑰和私鑰,他只要向“客戶”傳送他自己的私鑰就可以冒充“伺服器”了。示意如下:
如上場景“黑客”只需要自己生成一對公鑰和私鑰,然後把公鑰傳送給“客戶”,自己保留私鑰,這樣由於“客戶”可以用黑客的公鑰解密黑客的私鑰加密的內容,“客戶”就會相信“黑客”是“伺服器”,從而導致了安全問題。這裡問題的根源就在於,大家都可以生成公鑰、私鑰對,無法確認公鑰對到底是誰的。 如果能夠確定公鑰到底是誰的,就不會有這個問題了。例如,如果收到“黑客”冒充“伺服器”發過來的公鑰,經過某種檢查,如果能夠發現這個公鑰不是“伺服器”的就好了。
為了解決這個問題,數字證書出現了,它可以解決我們上面的問題。一個證書包含下面的具體內容:
- 證書的釋出機構
- 證書的有效期
- 公鑰
- 證書所有者(Subject)
- 簽名所使用的演算法
- 指紋以及指紋演算法
證書的內容的詳細解釋會在後面詳細解釋,這裡先只需要搞清楚一點,數字證書可以保證數字證書裡的公鑰確實是這個證書的所有者(Subject)的,或者證書可以用來確認對方的身份。也就是說,我們拿到一個數字證書,我們可以判斷出這個數字證書到底是誰的。至於是如何判斷的,後面會在詳細討論數字證書時詳細解釋。現在把前面的通訊過程使用數字證書修改為如下場景:
5、場景五
注意,上面第二次通訊,“伺服器”把自己的證書發給了“客戶”,而不是傳送公鑰。“客戶”可以根據證書校驗這個證書到底是不是“伺服器”的,也就是能校驗這個證書的所有者是不是“伺服器”,從而確認這個證書中的公鑰的確是“伺服器”的。後面的過程和以前是一樣,“客戶”讓“伺服器”證明自己的身份,“伺服器”用私鑰加密一段內容連同明文一起發給“客戶”,“客戶”把加密內容用數字證書中的公鑰解密後和明文對比,如果一致,那麼對方就確實是“伺服器”,然後雙方協商一個對稱加密來保證通訊過程的安全。
6、完成場景
7、場景完善(可忽略)
由於上述場景中存在一些遺漏,需要完善,具體內容見下文:
- 每次收到“客戶”發來的要加密的的字串時,“伺服器”並不是真正的加密這個字串本身,而是把這個字串進行一個hash計算,加密這個字串的hash值(不加密原來的字串)後傳送給“客戶”,“客戶”收到後解密這個hash值並自己計算字串的hash值然後進行對比是否一致。也就是說,“伺服器”不直接加密收到的字串,而是加密這個字串的一個hash值,這樣就避免了加密那些有規律的字串,從而降低被破解的機率。“客戶”自己傳送的字串,因此它自己可以計算字串的hash值,然後再把“伺服器”傳送過來的加密的hash值和自己計算的進行對比,同樣也能確定對方是否是“伺服器”。
- 為了防止“黑客”在雙方的通訊過程中把資訊原封不動的傳送多次,擾亂通訊過程(“黑客”可以截獲傳送的加密了的內容,但他無法解密這個內容)。可以給通訊的內容加上一個序號或者一個隨機的值,如果“客戶”或者“伺服器”接收到的資訊中有之前出現過的序號或者隨機值,那麼說明有人在通訊過程中重發資訊內容進行搗亂,雙方會立刻停止通訊。
- 為防止“黑客”修改截獲後的密文修改後再發送。“客戶”和“伺服器”是無法判斷密文是否被修改的。因此在每次傳送資訊時,先對資訊的內容進行一個hash計算得出一個hash值,將資訊的內容和這個hash值一起加密後傳送。接收方在收到後進行解密得到明文的內容和hash值,然後接收方再自己對收到資訊內容做一次hash計算,與收到的hash值進行對比看是否匹配,如果匹配就說明資訊在傳輸過程中沒有被修改過。如果不匹配說明中途有人故意對加密資料進行了修改,立刻中斷通話過程後做其它處理。
三、證書的構成和原理
1、證書的構成和原理
a)、windows上證書檢視
以ie和360為例,設定中找到Internet選項(360在工具中),如下圖:
選擇內容、證書,如下圖:
由於之前新增的自己生成的證書在受信任的根證書頒發機構內,選擇該證書,點選檢視:
在windows下檢視一個證書,本證書是一個自己生成的證書,我們主要關注一下Details Tab頁(詳細資訊內容),證書的主要內容包含以下(查看了其他的證書,發現詳細資訊內容會比較多):
查詢網上資料對幾個重要的解釋一下。
◆Issuer (證書的釋出機構)
指出是什麼機構釋出的這個證書,也就是指明這個證書是哪個公司建立的(只是建立證書,不是指證書的使用者)。對於上面的這個證書來說,就是指”SecureTrust CA”這個機構。
◆Valid from , Valid to (證書的有效期)
也就是證書的有效時間,或者說證書的使用期限。 過了有效期限,證書就會作廢,不能使用了。
◆Public key (公鑰)
這個我們在前面介紹公鑰密碼體制時介紹過,公鑰是用來對訊息進行加密的,第2章的例子中經常用到的。這個數字證書的公鑰是2048位的,它的值可以在圖的中間的那個對話方塊中看得到,是很長的一串數字。
◆Subject (主題)
這個證書是釋出給誰的,或者說證書的所有者,一般是某個人或者某個公司名稱、機構的名稱、公司網站的網址等。 對於這裡的證書來說,證書的所有者是Trustwave這個公司。
◆Signature algorithm (簽名所使用的演算法)
就是指的這個數字證書的數字簽名所使用的加密演算法,這樣就可以使用證書釋出機構的證書裡面的公鑰,根據這個演算法對指紋進行解密。指紋的加密結果就是數字簽名(第1.5節中解釋過數字簽名)。
◆Thumbprint, Thumbprint algorithm (指紋(hash值)以及指紋演算法(hash演算法))
這個是用來保證證書的完整性的,也就是說確保證書沒有被修改過,這東西的作用和2.7中說到的第3個問題類似。 其原理就是在釋出證書時,釋出者根據指紋演算法(一個hash演算法)計算整個證書的hash值(指紋)並和證書放在一起,使用者在開啟證書時,自己也根據指紋演算法計算一下證書的hash值(指紋),如果和剛開始的值對得上,就說明證書沒有被修改過,因為證書的內容被修改後,根據證書的內容計算的出的hash值(指紋)是會變化的。 注意,這個指紋會使用”SecureTrust CA”這個證書機構的私鑰用簽名演算法(Signature algorithm)加密後和證書放在一起。
b)、mac上chrome證書檢視
具體內容不在贅述,如下圖所示
注意,為了保證安全,在證書的釋出機構釋出證書時,證書的指紋和指紋演算法,都會加密後再和證書放到一起釋出,以防有人修改指紋後偽造相應的數字證書。這裡問題又來了,證書的指紋和指紋演算法用什麼加密呢?他們是用證書釋出機構的私鑰進行加密的。可以用證書釋出機構的公鑰對指紋和指紋演算法解密,也就是說證書釋出機構除了給別人釋出證書外,他自己本身也有自己的證書。證書釋出機構的證書是哪裡來的呢???這個證書釋出機構的數字證書(一般由他自己生成)在我們的作業系統剛安裝好時(例如windows xp等作業系統),這些證書釋出機構的數字證書就已經被微軟(或者其它作業系統的開發機構)安裝在作業系統中了,微軟等公司會根據一些權威安全機構的評估選取一些信譽很好並且通過一定的安全認證的證書釋出機構,把這些證書釋出機構的證書預設就安裝在作業系統裡面了,並且設定為作業系統信任的數字證書。這些證書釋出機構自己持有與他自己的數字證書對應的私鑰,他會用這個私鑰加密所有他釋出的證書的指紋作為數字簽名。
2、如何向證書的釋出機構去申請證書
舉個例子方便大家理解,假設我們公司”dong Company”花了1000塊錢,向一個證書釋出機構”SecureTrust CA”為我們自己的公司”dong Company”申請了一張證書,注意,這個證書釋出機構”SecureTrust CA”是一個大家公認並被一些權威機構接受的證書釋出機構,我們的作業系統裡面已經安裝了”SecureTrust CA”的證書。”SecureTrust CA”在給我們釋出證書時,把Issuer,Public key,Subject,Valid from,Valid to等資訊以明文的形式寫到證書裡面,然後用一個指紋演算法計算出這些數字證書內容的一個指紋,並把指紋和指紋演算法用自己的私鑰進行加密,然後和證書的內容一起釋出,同時”SecureTrust CA”還會給一個我們公司”dong Company”的私鑰給到我們。我們花了1000塊錢買的這個證書的內容如下:
×××××××××××××××證書內容開始×××××××××××××××××
Issuer : SecureTrust CA
Subject : dong Company
Valid from : 某個日期
Valid to: 某個日期
Public Key : 一串很長的數字
…… 其它的一些證書內容……
{證書的指紋和計算指紋所使用的指紋演算法}[SecureTrust CA的私鑰|RSA] //這個就是”SecureTrust CA”對這個證書的一個數字簽名,表示這個證書確實是他釋出的,有什麼問題他會負責(收了我們1000塊,出了問題肯定要負責任的)
×××××××××××××××證書內容結束×××××××××××××××××
// 前面的約定{} 表示RSA加密後的內容,[ | ]表示用什麼金鑰和演算法進行加密
我們”dong Company”申請到這個證書後,我們把證書投入使用,我們在通訊過程開始時會把證書發給對方,對方如何檢查這個證書的確是合法的並且是我們”dong Company”公司的證書呢?
首先應用程式(對方通訊用的程式,例如IE、OUTLook等)讀取證書中的Issuer(釋出機構)為”SecureTrust CA” ,然後會在作業系統中受信任的釋出機構的證書中去找”SecureTrust CA”的證書,如果找不到,那說明證書的釋出機構是個水貨釋出機構,證書可能有問題,程式會給出一個錯誤資訊。 如果在系統中找到了”SecureTrust CA”的證書,那麼應用程式就會從證書中取出”SecureTrust CA”的公鑰,然後對我們”dong Company”公司的證書裡面的指紋和指紋演算法用這個公鑰進行解密,然後使用這個指紋演算法計算”dong Company”證書的指紋,將這個計算的指紋與放在證書中的指紋對比,如果一致,說明”dong Company”的證書肯定沒有被修改過並且證書是”SecureTrust CA” 釋出的,證書中的公鑰肯定是”dong Company”的。對方然後就可以放心的使用這個公鑰和我們”dong Company”進行通訊了。