讀《圖解密碼技術》(二):認證

前一篇文章總結了密碼部分的內容,包括一次性密碼本、對稱密碼、公鑰密碼、混合密碼系統等。這些密碼在一定程度上能夠保證消息的機密性,即可以防止被竊聽導致祕密泄露。但卻無法防禦信息被篡改,也無法確定消息的來源是否就是真實的發送者而不是來自僞裝者,也防止不了發送者事後否認自己先前做過的行爲。關於這些問題,在本文總結的密碼技術中就可以找到解決方案。

本文是關於《圖解密碼技術》第二部分的內容總結,包括單向散列函數、消息認證碼、數字簽名、證書。

單向散列函數

使用單向散列函數可以獲取消息的“指紋”,通過對比“指紋”,就能夠知道兩條消息是否一致。這種一致性,也稱爲完整性,可以識別出消息是否被篡改。

單向散列函數(one-way hash function)有一個輸入和一個輸出,其中輸入稱爲 消息 (message),輸出稱爲 散列值 (hash value)。散列值也稱爲 消息摘要 (message digest)或者 指紋 (fingerprint)。單向散列函數可以根據消息的內容計算出散列值,而散列值就可以用來檢查消息的完整性。

單向散列函數的性質

根據任意長度的消息計算出固定長度的散列值

首先,單向散列函數的輸入必須能夠是任意長度的消息。其次,無論輸入多長的消息,必須都能夠生成很短的散列值。如果消息越長生成的散列值也越長的話就不好用了,而且爲了方便使用,散列值的長度最好是短且固定的。不管消息是1比特,還是100M,甚至是100G,單向散列函數都會計算出固定長度的散列值。比如,SHA-1計算出的散列值固定爲160比特(20字節)。

能夠快速計算出散列值

計算散列值所花費的時間必須要短。儘管消息越長,計算散列值的時間也會越長,但如果不能在現實的時間內完成計算就沒有意義了。

具備單向性

單向散列函數必須具備單向性。單向性是指無法通過散列值反算出消息的性質。就如同將玻璃砸得粉碎很容易,但卻無法將碎片還原成完整的玻璃一樣,根據消息計算出散列值很容易,但根據散列值卻無法反算出消息。

消息不同散列值也不同

爲了能夠確認完整性,消息中哪怕只有 1 比特的改變,也必須有很高的概率產生不同的散列值。爲什麼說有很高的概率呢?這是因爲消息很長,而散列值很短,那就肯定會存在不同消息產生相同散列值的情況,這種情況稱爲 碰撞 (collision)。因此,單向散列函數沒法完全避免碰撞,只能減低碰撞發生的概率。而且,更重要的是,要避免被人爲地發現碰撞。難以發現碰撞的性質稱爲 抗碰撞性 (collision resistance)。單向散列函數必須具備抗碰撞性。另外,抗碰撞性還分爲兩種:弱抗碰撞性和強抗碰撞性。 弱抗碰撞性*是指要找到和給定的消息具有相同散列值的另外一條消息是非常困難的。 強抗碰撞性**則是指要找到散列值相同的兩條不同的消息是非常困難的。單向散列函數必須既具備弱抗碰撞性,也必須具備強抗碰撞性。

單向散列函數的例子

單向散列函數有很多種,MD4、MD5、SHA-1、SHA-256、SHA-384、SHA-512、SHA-3等等。

MD4是由Rivest於1990年設計的,MD是消息摘要(message digest)的縮寫,兩者都能夠產生128比特的散列值。不過,第二年,即1991年,就已經有人提出了MD4的漏洞,很容易就尋找到了MD4散列碰撞的方法。因此,Rivest又設計了更爲成熟的MD5。MD5到現在依然有着廣泛的應用,例如很多網站和應用的登錄密碼都使用了MD5。但MD5的強抗碰撞性已經被攻破,也就是說,現在已經能夠產生具備相同散列值的兩條不同的消息。所以,其實MD5已經不安全了。

SHA是NSA(美國國家安全局)設計,NIST(美國國家標準與技術研究院)發佈的一系列單向散列函數。SHA是以MD4和MD5類似的原理爲基礎來設計的。SHA-1能夠產生160比特的散列值,不過消息長度是有上限的,上限爲2^64比特(準備地說是2^64-1)。當然這個數已經非常巨大,所以在實際應用中沒有問題。不過,SHA-1的強抗碰撞性已於2005年被攻破。所以,SHA-1也和MD5一樣沒那麼安全了。不過,貌似SHA-1依然是目前使用最廣泛的單向散列函數。

SHA-256、SHA-384和SHA-512的散列值長度分別爲256比特、384比特和512比特。它們的消息長度也存在上限,SHA-256的上限和SHA-1一樣,而SHA-384和SHA-512的消息上限則爲2^128比特(確切值爲2^128-1)。這些單向散列函數合起來稱爲SHA-2。目前,SHA-2還沒有被攻破。

在2005年SHA-1被攻破的背景下,促進了SHA-3的產生。SHA-3與AES一樣採用了公開競賽的方式進行標準化,最後勝出的是Keccak算法。

單向散列函數SHA-1

SHA-1作爲一個具有代表性的單向散列函數,讓我們看看它的算法流程是怎樣的。整體流程如下圖:

 

\

 

可以分爲四個步驟:

填充

對消息進行填充處理,使其長度爲512比特的整數。這裏的512比特稱爲一個輸入分組。具體填充的步驟也分爲三步:第一步在消息末尾添加一個1比特的數值“1”;第二步在添加了“1”之後的消息末尾不斷添加0,直到消息的長度達到512比特的整數倍,但最後一個分組的最後64比特需要空出來;第三步將消息的長度換成二進制後添加到上一步空出來的最後一個分組的最後64比特中。

計算 W0 ~ W79

對每一個輸入分組分別計算80個32比特的值,這80個值將用於“單步處理“中。計算流程如下圖:

 

\

 

首先,將輸入分組的512比特分成16組,每組32比特。然後,剩下的 W16 ~ W79 使用如下的公式進行計算:

 

\

 

分組處理

接下來,對輸入分組進行80個步驟的處理,目的是根據輸入分組的信息來改變內部狀態。流程如下圖,其中,160比特的內部狀態是通過名爲A~E的5個32比特的緩衝區來表示的:

 

\

 

將5個緩衝區的值與輸入分組的信息進行混合,然後再執行80個步驟的處理。從結果來看,這80個步驟所完成的操作,就是將輸入分組的512比特的數據,也SHA-1所保持的160比特的內部狀態(5個緩衝區)進行混合。通過80個步驟的反覆執行,SHA-1就能夠將已經過填充的消息全部混入這160比特的內部狀態中,而SHA-1所輸出的散列值,就是所有處理結束之後最終的內部狀態(160比特)。

單步處理

單步處理是指上面的80個步驟中的每一步的處理,處理過程如下圖:

 

\

 

在一個步驟完成之後,緩衝區A、B、C、D的內容會被分別複製到B、C、D、E中(其中B要循環左移30比特之後再複製),而緩衝區 E 的內容則會與其他緩衝區的內容以及Wt、Kt相加之後再被複制到緩衝區A中。

由於上述處理要循環80個步驟,因此輸入分組中 1 比特的變化,就會影響到散列值中幾乎所有的比特,通過這樣的方式,就能夠實現單向散列函數所應具備的性質。

對單向散列函數的攻擊

對單向散列函數的攻擊主要就是對單向散列函數的”抗碰撞性“的攻擊。

對“弱抗碰撞性”的攻擊主要是利用消息的冗餘性生成具有相同散列值的另一個消息,這種攻擊也是 暴力破解 ,每次都稍微改變一下消息的值,然後對這些消息求散列值。在這種情況下,暴力破解需要嘗試的次數可以根據散列值的長度計算出來。以SHA-1爲例,由於它的散列值長度爲160比特,因此最多隻要嘗試2^160次就能夠找到目標消息。由於嘗試次數純粹是由散列值長度決定的,因此散列值長度越長的單向散列函數,其抵禦暴力破解的能力也就越強。

對“強抗碰撞性”的攻擊一般稱爲 生日攻擊 。生日攻擊不是尋找生成特定散列值的消息,而是要找到相同散列值的兩條消息,而散列值則可以是任何值。生日攻擊的原理來自生日悖論,也就是利用了“任意散列值一致的概率比想象中高”這樣的特性。相對於暴力破解,生日攻擊所需嘗試的次數要少得多,一般只需要是暴力破解的一般。

單向散列函數無法解決的問題

單向散列函數可以實現完整性的檢查,但卻識別不了“僞裝”,即無法解決認證問題。認證問題需要使用消息認證碼和數字簽名來解決。

單向散列函數在實際應用中很少單獨使用,而是和其他密碼技術結合使用。後面要講的消息認證碼和數字簽名都使用了單向散列函數,而下一篇要講的密鑰、僞隨機數和應用技術也都使用了單向散列函數。

消息認證碼

消息認證碼(message authentication code)是一種確認完整性並進行認證的技術,簡稱爲 MAC 。消息認證碼的輸入包括任意長度的 消息 和一個發送者與接受者之間 共享的密鑰 ,它可以輸出固定長度的數據,這個數據稱爲 MAC 值 。

消息認證碼與單向散列函數很類似,都是根據任意長度的消息輸出固定長度的數據,不同的是,消息認證碼比單向散列函數多了一個共享密鑰。沒有共享密鑰的人就無法計算出 MAC 值,消息認證碼正是利用這一性質來完成認證的。此外,和單向散列函數一樣,哪怕消息中發生 1 比特的變化,MAC 值也會發生變化,消息認證碼正是利用這一性質來確認完整性的。

消息認證碼的使用步驟

消息認證碼的使用步驟如下圖:

 

\

 

發送者與接收者需要事先共享密鑰,然後發送者使用共享密鑰對消息計算 MAC 值,接着將消息和 MAC值一起發送給接收者。接收者收到消息和 MAC 值後,使用同一個共享密鑰對消息計算 MAC 值,當計算出來的 MAC 值和接收到的 MAC 值一致的,就證明認證成功了。

而既然是使用共享密鑰,那就和對稱密碼一樣,存在密鑰配送問題。要解決密鑰配送問題,同樣可以使用事先共享密鑰、密鑰配送中心、Diffie-Hellman密鑰交換、公鑰密碼等方法。具體請看前一篇文章的 密鑰配送問題 部分。

消息認證碼的實現

消息認證碼有很多種實現方法。可以使用SHA-1、MD5之類的 單向散列函數 來實現,其中有一種實現方法叫 HMAC ,後面我們再講它實現的具體步驟。

也可以使用DES、AES之類的 分組密碼 來實現消息認證碼,將分組密碼的密鑰作爲消息認證碼的共享密鑰來使用,並用 CBC 模式將消息全部加密。由於消息認證碼不需要解密,因此,可以只保留最後一個分組的密文作爲 MAC 值,而其他密文則全部丟棄。由於 CBC 模式的最後一個分組會收到整個消息以及密鑰的雙重影響,因此可以將它用作消息認證碼。

此外,使用流密碼和公鑰密碼等也可以實現消息認證碼。

HMAC

HMAC是一種使用單向散列函數來構造消息認證碼的方法,其中,HMAC 中的 H 就是 Hash 的意思。HMAC 中所使用的單向散列函數並不僅限於一種,任何高強度的單向散列函數都可以被用於 HMAC,也就是說,HMAC 所使用的單向散列函數是可以被替換的。

HMAC 是按照下列步驟來計算 MAC 值的:

 

\

 

密鑰填充如果密鑰比單向散列函數的分組長度要短,就需要在末尾填充0,直到其長度達到單向散列函數的分組長度爲止。如果密鑰比分組長度要長,則要用單向散列函數求出密鑰的散列值,然後將這個散列值用作 HMAC 的密鑰。

填充後的密鑰與 ipad 的 XOR

將填充後的密鑰與被稱爲 ipad 的比特序列進行 XOR 運算。 ipad 是將 00110110 這一比特序列(即16進制的36)不斷循環反覆直到達到分組長度所形成的比特序列,其中 ipad 的 i 是 inner 的意思。XOR 運算後得到的值,就是一個和單向散列函數分組長度相同,且和密鑰相關的比特序列。這裏將這個比特序列稱爲 ipadkey 。

與消息組合隨後,將 ipadkey 與消息進行組合,ipadkey 一般附加在消息開頭。

計算散列值將上一步組合的結果輸入單向散列函數,計算出散列值。

填充後的密鑰與 opad 的 XOR

將填充後的密鑰與被稱爲 opad 的比特序列進行 XOR 運算。 opad 是將 01011100 這一比特序列(即16進制的5C)不斷循環反覆直到達到分組長度所形成的比特序列,其中 opad 的 o 是 outer 的意思。XOR 運算後得到的值,也是一個和單向散列函數分組長度相同,且和密鑰相關的比特序列。這裏將這個比特序列稱爲 opadkey 。

與散列值組合將第4步計算出來的散列值拼在 opadkey 的後面。

計算散列值將上一步的結果輸入單向散列函數,計算出散列值。這個散列值就是 MAC 值。

對消息認證碼的攻擊

對消息認證碼可以發起 重放攻擊 ,即攻擊者可以通過將事先攔截保存的正確 MAC 值不斷重放來發動攻擊。有幾種方法可以防禦重放攻擊:

序號每次發送消息時都賦予一個遞增的序號,並在計算 MAC 值時將序號也包含在消息中。這樣,由於攻擊者無法計算序號遞增之後的 MAC 值,因此就可以防禦重放攻擊。這種方法雖然有效,但對每個通信對象都需要記錄最後一個消息的序號。

時間戳發送消息時可以包含進當前時間,如果收到以前的消息,即便 MAC 值正確也將其視爲錯誤的消息來處理,這樣就可以防禦重放攻擊。這種方法雖然也有效,但發送者與接收者的時鐘必須一致,而且考慮到通信的延遲,必須在時間的判斷上留下緩衝,於是多多少少還是會存在可以進行重放攻擊的控件。

nonce

在通信之前,接收者先向發送者發送一個一次性的隨機數,這個隨機數一般稱爲 nonce 。發送者在消息中包含這個 nonce 並計算 MAC 值。由於每次通信時 nonce 的值都會發生變化,因此無法進行重放攻擊。這種方法雖然有效,但通信的數據量會有所增加。

另外,除了重放攻擊,對消息認證碼也可以進行暴力破解和生日攻擊,這和對單向散列函數的攻擊一樣。對消息認證碼來說,應保證不能根據 MAC 值推測出通信雙方所使用的密鑰。例如 HMAC 就是利用單向散列函數的單向性和抗碰撞性來保證無法根據 MAC 值推測出密鑰的。

消息認證碼無法解決的問題

使用消息認證碼可以對消息進行認證並確認完整性,即能夠識別出消息的篡改和僞裝。但卻解決不了“對第三方證明”和“防止否認”。

假如接收者在收到發送者的消息之後,想要向第三方證明這條消息的確是發送者發送的,但是用消息認證碼無法進行這樣的證明,爲什麼呢?首先,第三方要校驗 MAC 值,就需要知道發送者與接收者之間共享的密鑰。但知道密鑰後,也校驗出 MAC 值是正確的,依然無法證明消息就是發送者發的,因爲也有可能是接收者發的。

既然第三方無法做出證明,那麼,如果發送者事後否認自己發送過消息,而謊稱是接收者自己發送給自己的消息,對於這種情況也是無法證明,即無法防止否認。

後面要講的數字簽名就可以解決這兩個問題。

數字簽名

消息認證碼之所以無法對第三方證明和防止否認,就是因爲發送者和接收者使用了同一個共享密鑰。那麼,如果發送者和接收者不使用共享密鑰,而各自使用不同密鑰呢?假如發送者使用的密鑰是一個只有自己知道的私鑰,在這裏可稱爲“簽名密鑰”,當發送者發送消息時,用她的簽名密鑰生成一個“簽名”。相對地,接收者使用另一個密鑰,稱爲“驗證密鑰”,可對簽名進行驗證。但是,使用驗證密鑰是無法生成簽名的。也就是說,只有簽名密鑰可以生成簽名,而用相應的驗證密碼可以對該簽名進行驗證。這種技術就是 數字簽名 (digital signature),也稱爲 電子簽名 ,或簡稱爲 簽名 。另外,簽名密鑰只能由簽名的人持有,而驗證密鑰則是任何需要驗證簽名的人都可以持有。

上面講的內容,和公鑰密碼很像吧?其實,數字簽名就是通過將公鑰密碼反過來用而實現的。

公鑰密碼與數字簽名

下圖是使用公鑰加密(即公鑰密碼)的簡單流程圖:

 

\

 

而下圖則是使用私鑰加密(即數字簽名)的簡單流程圖:

 

\

 

那麼,爲什麼用私鑰加密就相當於生成簽名,而用公鑰解密就相當於驗證簽名呢?這是因爲組成密鑰對的兩個密鑰之間存在嚴密的數學關係,使用公鑰加密的密文,只能用與該公鑰配對的私鑰才能解密;同樣地,使用私鑰加密的密文,也只能用與該私鑰配對的公鑰才能解密。也就是說,如果用某個公鑰成功解密了密文,那麼就能夠證明這段密文是用與該公鑰配對的私鑰進行加密所得到的。用私鑰進行加密這一行爲只能由持有私鑰的人完成,正式基於這一事實,纔可以將用私鑰加密的密文作爲簽名來對待。而由於公鑰是對外公開的,因此任何人都可以用公鑰進行解密,即任何人都能夠對簽名進行驗證。

數字簽名的方法

有兩種生成和驗證數字簽名的方法:

直接對消息簽名的方法

直接對消息簽名的方法很容易理解,但實際上很少使用。簽名和驗證的過程如下圖:

 

\

 

我們知道,公鑰密碼算法本來就非常慢。用這種方法需要對整個消息進行加密,就會非常耗時。因此,在實際應用中,基本不會使用直接對消息簽名的方法。

對消息的散列值簽名的方法

對消息先使用單向散列函數計算出散列值,再對散列值進行簽名,這種方法的過程如下圖:

 

\

 

因爲散列值比較短,因此對其進行加密簽名就會快很多。

數字簽名的實現

數字簽名的實現也有很多種,基本也是使用單向散列函數和公鑰密碼技術相結合。而公鑰密碼部分常用的就是使用RSA,另外也有使用EIGamal、Rabin。還有一種數字簽名算法叫DSA(Digital Signature Algorithm)。而使用最廣泛的應該就是使用RSA的數字簽名了。

使用RSA實現數字簽名很簡單。而爲了更加簡單起見,這裏不使用單向散列函數,而是直接對消息進行簽名。首先,需要將文本的消息先編碼爲數字,因爲在RSA中,被簽名的消息、密鑰以及最終生成的簽名都是以數字形式表示的。接着,使用下列公式生成簽名:

簽名 = 消息^D mod N (用RSA生成簽名)

D 和 N 就是簽名者的私鑰。生成簽名後,發送者就可以將消息和簽名一起發送給接收者了。

而驗證簽名時則使用下列公式:

由簽名求得的消息 = 簽名^E mod N (用RSA驗證簽名)

E 和 N 就是簽名者的公鑰。接收者計算出“由簽名求得的消息”後,與發送者直接發送過來的“消息”內容進行對比(如果使用了單向散列函數那就是對比消息的散列值)。如果兩者一致則簽名驗證成功,否則簽名驗證失敗。

對數字簽名的攻擊

因爲數字簽名結合了單向散列函數和公鑰密碼,因此,對單向散列函數和公鑰密碼的攻擊也同樣對數字簽名有效。比如,針對公鑰密碼的中間人攻擊對數字簽名來說就頗具威脅。要防止中間人攻擊,就需要確認自己所得到的公鑰是否真的屬於自己的通信對象。而解決此問題的方案也和公鑰密碼一樣,一般可以使用公鑰證書。

對單向散列函數的攻擊也是對“抗碰撞性”的攻擊,使用高強度的單向散列函數就可以增大被破解的難度。

另外,還可以利用數字簽名攻擊公鑰密碼。因爲對消息簽名,從另一方面來說,也是對消息解密。利用這一點,攻擊者就可以發動一種巧妙的攻擊,即利用數字簽名來破譯密文。

假設攻擊者攔截到發送者發給接收者的密文後將其保存了下來,並給接收者寫了一封郵件,謊稱自己是密碼學研究者,正在進行關於數字簽名的實驗,請求接收者對附件中的數據進行簽名並回復,說附件中的數據只是隨機數據,不會造成任何問題。而實際上,附件的數據就是剛纔保存下來的密文。如果接收者中計而對附近進行了簽名並回復給了攻擊者,那攻擊者不費吹灰之力就可以破譯密文了。

對於這種攻擊,應該採取怎樣的對策呢?首先,不要直接對消息進行簽名,對散列值進行簽名比較安全;其次,公鑰密碼和數字簽名最好分別使用不同的密鑰對。然而,最重要的就是絕對不要對意思不清楚的消息進行簽名,尤其是不要對看起來只是隨機數據的消息進行簽名。

數字簽名無法解決的問題

用數字簽名既可以識別出篡改和僞裝,還可以防止否認。即是說,數字簽名同時實現了確認消息的完整性、進行認證以及否認防止。

然而,數字簽名存在和公鑰密碼一樣的問題,那就是公鑰問題。公鑰必須屬於真正的發送者,要確認公鑰是否合法,就需要使用證書。這就是後面要講到的內容了。

證書

無論是公鑰密碼還是數字簽名,都存在需要驗證公鑰是否合法的問題。而證書,就是用來對公鑰合法性提供證明的技術。

公鑰證書(Public-Key Certificate,PKC)和駕照類似,一般會記有姓名、組織、郵箱地址等個人信息,以及屬於本人的公鑰,並由 認證機構 (Certification Authority、Certifying Authority,CA)施加數字簽名。

認證機構就是能夠認定“公鑰確實屬於此人”並能夠生成數字簽名的個人或組織。認證機構中有國際性組織和政府所設立的組織,也有通過提供認證服務來盈利的一般企業,此外個人也可以成立認證機構哦。世界上最有名的認證機構當屬VeriSign公司。

證書的應用場景

通過認證機構使用證書的過程如下圖所示:

 

\

 

1. 接收者生成密鑰對;

2. 接收者在認證機構註冊自己的公鑰;

3. 認證機構用自己的私鑰對接收者的公鑰施加數字簽名並生成證書;

4. 發送者得到帶有認證機構數字簽名的屬於接收者的公鑰證書;

5. 發送者使用認證機構的公鑰驗證數字簽名,驗證通過則證明證書中包含的公鑰的確屬於接收者的;

6. 發送者用接收者的公鑰加密消息併發送給接收者;

7. 接收者用自己的私鑰解密密文得到消息。

公鑰基礎設施(PKI)

公鑰基礎設施(Public-Key Infrastructure)是爲了能夠更有效地運用公鑰而制定的一系列規範和規格的總稱。公鑰基礎設施一般根據其英語縮寫而簡稱爲PKI。PKI只是一個總稱,而並非指某一個單獨的規範或規格。比如,使用最廣泛的 X.509 規範也是PKI的一種。

PKI的組成要素主要有3個:

用戶 :使用PKI的人

認證機構 :頒發證書的人

倉庫 :保存證書的數據庫

這三者的關係如下圖:

 

\

 

另外,認證機構會有層級的關係,處於最頂層的認證機構一般就稱爲 根CA (Root CA)。上層認證機構可以驗證下層認證機構的證書,即是說,下層認證機構的證書是經過上層認證機構簽名的。而根CA則會對自己的證書進行簽名,這叫 自簽名 。認證機構的層級關係如下圖:

 

\

 

當發送者需要對最底層的Bob的數字簽名進行驗證時,首先從最頂層的根CA開始,然後獲得下層的公鑰證書,這個證書上面會帶有上層的數字簽名,因此需要用上層的公鑰對數字簽名進行驗證。這樣逐層向下驗證,一直驗證到最底層的Bob。

對證書的攻擊

由於證書使用的就是數字簽名技術,因此針對數字簽名的所有攻擊方法對證書都有效。

另外,在公鑰註冊之前也可以進行攻擊。用戶準備在認證機構註冊自己的公鑰時,攻擊者可以把消息攔截,然後將公鑰替換成自己的。這樣一來,認證機構就會對“接收者的個人信息”和“攻擊者的公鑰”這個組合進行數字簽名。要防止這種攻擊,接收者可以在將自己的公鑰發送給認證機構進行註冊時,使用認證機構的公鑰對自己的公鑰進行加密。此外,認證機構在確認接收者的身份時,也可以將公鑰的指紋(即散列值)一併發送給接收者請他進行確認。

攻擊者還可以利用註冊相似人名進行攻擊。證書是認證機構對公鑰及其持有者的信息加上數字簽名的產物,對於一些相似的身份信息,計算機可以進行區別,但人類往往很容易認錯,而這就可以被用來進行攻擊。比如,假設用戶信息中名字的部分是:

Name = Bob (首字母大寫)

而攻擊者用另一個類似的用戶信息註冊了另一個不同的公鑰:

Name = BOB (所有字母大寫)

隨後,攻擊者僞裝成Bob,將 Name = BOB 的公鑰發送給通信對象Alice,Alice看到證書中的用戶信息,很可能會將BOB誤認爲是自己要發送消息的對象Bob。

要防止這種攻擊,認證機構必須確認證書中所包含的信息是否真的是其持有者的個人信息,當本人身份確認失敗時則不向其頒發證書。

攻擊者也可以竊取認證機構的私鑰,不過認證機構對私鑰的保護是非常嚴密的,所以一般比較難竊取。如果認證機構的私鑰泄露了,認證機構就需要將私鑰泄露一事通過 CRL 通知用戶。CRL(Certificate Revocation List)爲證書作廢清單,是認證機構宣佈作廢的證書一覽表,具體來說,是一張已作廢的證書序列號的清單,並由認證機構加上了數字簽名。

利用鑽上面提到的 CRL 的空子也可以進行攻擊。因爲從公鑰失效到發送者收到 CRL 需要經過一段時間,攻擊者就可以利用這段時間差來發動攻擊。

關於證書的 Q&A

爲什麼需要證書 如果從認證機構獲取公鑰,就可以降低遭到中間人攻擊的風險。因爲帶有證書的公鑰是經過認證機構進行數字簽名的,事實上無法被篡改。

其實,如果能夠取得可信的公鑰,比如通信雙方在同一個辦公室,很容易取得可信的公鑰,這種情況下則不需要認證機構。否則,認證機構和證書的存在就有意義了。當持有可信的認證機構公鑰,並相信認證機構所進行的身份確認的情況下,則可以信任該認證機構頒發的證書以及通過該途徑取得的公鑰。

通過自己的方法進行認證是不是更安全 有些人對使用公開的技術總覺得不放心,使用公開的技術等於爲攻擊者提供了用於攻擊的信息,相比之下,還是使用公司自己開發的保密的認證方法更安全吧?

其實這是錯誤的。自己開發保密的方法是犯了典型的 隱蔽式安全 (security by obscurity)錯誤。私下開發安全相關的技術其實是危險的,僅靠一家公司的力量無法開發出足以抵禦攻擊的安全技術。這也是爲什麼 AES 和 RSA 算法要採用公開競賽的方式,讓全世界的安全專家一起來驗證這些技術的安全性。

爲什麼要相信認證機構

其實,這個問題關係到“信任是如何產生的”這一本質性問題。爲什麼我們要把錢存進銀行呢?認證機構是否讓人感到可信,和銀行是一樣的。

也有不依賴於認證機構的,PGP 軟件就是。PGP 是通過 信任網 的方法來建立每個人之間的信任關係的。下一篇文章再具體講 PGP。

寫在最後

本篇文章總結了四部分內容:單向散列函數、消息認證碼、數字簽名和證書。數字簽名的安全性最高,既能確保完整性,也能進行認證和防止否認。另外,數字簽名也是將單向散列函數和公鑰密碼技術相結合在了一起。前一篇文章所講的混合密碼系統也是結合了多種技術。其實,實用性的安全產品,都是多種密碼技術組合在一起實用的。例如,PGP、SSL\TLS等。下一篇就會講如何將多種密碼技術組合在一起。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章