在上一章裡當我們討論“安全(security)”時,其實我們指的是訊息的私密性(secrecy)。訊息具有私密性,是指具有防止被一個竊聽者得知其內容的能力。但有時相比於私密性,我們更在意訊息的真實性(authetication)。例如在網購時,或許商家並不在意顧客的訂單是否洩露給某些竊聽者,而更關心訂單的來源以及內容是否被惡意篡改過。私密性和真實性作為安全的兩個方面實際上並不具有實際關聯,我們之間所討論的加密(encryption)對保護訊息真實性沒有任何實質的幫助,它確實能夠透過不讓敵手知道密文的含義而只能做出不基於文字的修改, 但並不為“監測訊息是否被修改過”這一目的做出任何貢獻。很多時候,只要篡改訊息的一個二進位制位就有可能徹底改變訊息的本意。
訊息認證碼(Message Authentication Codes, MACs)
我們想要實現在私鑰加密的背景下,接收方能夠判定接收到的訊息是否經過篡改。要能實現這一點,傳送方和接收方肯定要提前掌握某些敵手所沒有的資訊(像私鑰一樣),否則接收方便與敵手無異。
在下面這種基於稱為訊息認證碼(MAC)的方案中,傳送方和接收方提前約定要一個私鑰\(k\)(這裡我們沒有討論有關加密的任何事情,這個私鑰可能不同於加密時的私鑰),一個程式\(\text{Mac}\)基於\(k\)和要傳送的訊息\(m\)生成一個字串\(t\),稱為標籤(tag)(\(\text{Mac}\)可能是確定性的,可能是非確定性的)。接收方執行一個驗證程式\(\text{Vrfy}\),輸入\(m,t\)輸出\(t\)是否是一個合法的標籤(0或1)。我們要求\(\text{Vrfy}_k(m,\text{Mac}_k(m))=1\)必須始終成立。可以看出,接收方就是透過驗證程式的輸出來判斷訊息真實性的。
如果\(\text{Mac}\)是一個確定性的程式,那麼\(\text{Vrfy}\)的最簡單也最標準的實現方式就是再次執行\(\text{Mac}\)然後比較兩次得到的標籤,標籤合法當且僅當兩次的輸出相同。這稱為標準驗證(canonical verification)。
如何定義一個MAC方案是否安全(secure)呢?我們假設敵手能夠截獲訊息明文以及對應的標籤,這意味著敵手實際上擁有選擇任何明文並得知其標籤的能力。如果敵手能夠生成一個從未傳送過的訊息的標籤,那麼當它把這條訊息連同敵手自己生成的標籤傳送給接收方時,訊息的來源就無法辨別,敵手就成功破解了這一MAC方案。所以我們可以基於以下實驗定義MAC方案的安全性:敵手可以詢問多項式次訊息對應的標籤,如果敵手能夠基於一個它未詢問過的訊息給出一個合法的標籤,就稱敵手成功。如果敵手成功的機率\(\leq \text{negl}(n)\),就稱當前MAC是不可偽造的(unforgeable),也即這一MAC方案是安全的。
必須指出,以上MAC方案的定義是不針對重放攻擊(replay attacks)的。想象傳送方發過\((m,t)\),那麼敵手只需重複傳送\((m,t)\),接收方就完全不能判斷訊息來源。這很多時候是危險的,例如網購時顧客下單了一次,敵手做重放攻擊九次,店家就要顧客交十倍的錢。這是由於MAC的定義中不涉及任何關於狀態的量(it is stateless),一些能夠保證通訊雙方同步(synchronized)的方案可以緩解這一問題。
另一方面,如果標籤的生成程式是非確定性的,那麼以上安全性的定義中也沒有排除敵手關於已傳送過的訊息生成了另一個不同的合法標籤的情況。為了囊括這一情形,可以在安全性的定義中把“未詢問過的訊息”改為“未詢問過的訊息和標籤的二元組\((m,t)\)”,這樣定義的MAC稱為強不可偽造的(strongly unforgeable)。容易發現標準驗證下的MAC一定是強不可偽造的。
在實際中,敵手還可以不停給接收方傳送二元組\((m,t)\)從而確認當前偽造的標籤是否合法,也就是我們實際上在定義中應該假定敵手有確認標籤是否合法的能力。我們之所以在定義中沒有提到這點,是因為可以證明強不可偽造性下擁有這種能力並不會增加敵手成功的機率。然而,在實際中這一確認標籤的能力確實會引發問題。假如接收方的驗證程式是按位比較兩個字串,在第一次遇到不同字元時立馬停機返回,那麼敵手就可以根據檢驗程式返回輸出的時間差來直到得知第一個出錯的位置,改正它並不斷重複以上操作敵手就能最終偽造出一個合法的標籤。這一攻擊並不是基於我們假定的模型的,而是利用了真實物理世界中的時間資訊。這類方法稱為側通道攻擊(side-channel attacks)。為了防止這一攻擊,我們可以要求MAC的檢驗程式的輸出時間必須是與輸入無關的(比如比較完所有位置再返回)。
一個具體的MAC的構造
還沒寫。