消息認(rèn)證碼
消息認(rèn)證碼的作用
-
消息認(rèn)證碼同時(shí)解決消息的完整性和發(fā)送者正確性。
- 消息完整性解決的是消息是否有被篡改的問題,也就是保證了消息的完整性。
- 消息認(rèn)證解決的是消息的發(fā)送者正確性的問題,確保消息不是其他人偽裝發(fā)送的。
什么是消息認(rèn)證碼
- 是一種確認(rèn)完整性并進(jìn)行認(rèn)證的技術(shù),英文是message authentication code,簡稱MAC。
- 消息認(rèn)證碼的輸入是任意長度的消息和一個(gè)發(fā)送者與接收者之間共享的密鑰,輸出是固定長度的數(shù)據(jù),這個(gè)數(shù)據(jù)稱為MAC值。
- 從上面的輸入和輸出關(guān)系,我們很容易想到,消息認(rèn)證碼和單向散列函數(shù)有相似之處。所以可以理解為,消息認(rèn)證碼是一種與密鑰相關(guān)聯(lián)的單向散列函數(shù)。
- 單向散列函數(shù)保證了完整性,無法被篡改;共享密鑰只有發(fā)送者和接收者知道,保證了可以檢查發(fā)送者身份的正確性。
消息認(rèn)證碼使用過程
- 發(fā)送者發(fā)送消息后,使用發(fā)送的消息和共享密鑰計(jì)算出MAC值,并發(fā)送給接收者
- 接收者接收到消息后,使用接收到的消息和共享密鑰計(jì)算出MAC值
- 接收者接收到MAC值后,使用接收到的MAC值和自己計(jì)算的MAC值做比對。如果相同,則表示消息沒有被篡改,且發(fā)送者的身份正確。
共享密鑰配送問題
從上面的描述中可以得出,消息認(rèn)證碼能夠檢查發(fā)送者身份的關(guān)鍵因素就是共享密鑰。所以,共享密鑰的配送問題就是關(guān)鍵環(huán)節(jié)。
解決的辦法在第五章的公鑰章節(jié)中有總結(jié),基本也就包括:公鑰、Diffie-Hellman密鑰交換等解決思路。
消息認(rèn)證碼實(shí)例
-
SWIFT
全稱是 Society for Worldwide Interbank Financial Telecommunication(環(huán)球銀行金融電信協(xié)會),銀行與銀行之間傳遞交易消息是使用SWIFT,使用了消息認(rèn)證碼保障完整性和對消息進(jìn)行驗(yàn)證。
共享密鑰在使用公鑰密碼之前,是用人進(jìn)行配送的。 -
IPsec
此協(xié)議是針對IP協(xié)議增加愛安全性的一種方式,使用消息認(rèn)證碼對消息內(nèi)容進(jìn)行認(rèn)證和保證完整性。 -
SSL/TLS
這個(gè)后續(xù)會有專門章節(jié)進(jìn)行介紹。
消息認(rèn)證碼的實(shí)現(xiàn)方法
消息認(rèn)證碼有多種實(shí)現(xiàn)方式:
- 使用SHA-1等單向散列函數(shù)實(shí)現(xiàn),其中一種實(shí)現(xiàn)方式為HMAC。
- 使用AES等分組密碼實(shí)現(xiàn)。
- 分組的密鑰作為共享密鑰。
- 使用CBC模式進(jìn)行加密。簡單回顧一下CBC模式,就是前一個(gè)分組的密文與此分組的明文XOR后,再加密生成當(dāng)前分組的密文。
- 由于不需要進(jìn)行解密,所以只保留最后一個(gè)分組。由于最后一個(gè)分組會受到密鑰和整個(gè)消息的雙重影響,所以可以作為消息認(rèn)證碼。
- 流密碼和公鑰密碼也可以實(shí)現(xiàn)消息認(rèn)證碼。
HMAC詳細(xì)介紹
什么是HMAC
HMAC的H是hash的意思,就是使用單向散列函數(shù)來實(shí)現(xiàn)的消息認(rèn)證碼。
單向散列函數(shù)的具體算法隨意選擇,如果使用SHA-1,則被稱為HMAC-SHA-1。
HMAC具體步驟
-
密鑰填充
如果共享密鑰小于散列值的長度,則用0補(bǔ)充。
如果共享密鑰大于散列值的長度,則使用單向散列函數(shù)計(jì)算出共享密鑰的散列值。 -
填充后的密鑰與ipad的XOR
ipad是一種比特序列,是使用00110110這一比特序列不斷循環(huán)直到分組長度的比特序列。i是inner的意思。
填充后的密鑰和ipad XOR計(jì)算后的值稱為 ipadkey。 -
與消息組合
將ipadkey附在消息的開頭。 -
計(jì)算散列值
使用單向散列函數(shù)計(jì)算消息和ipadkey組合的散列值。 -
填充后的密鑰與opad XOR
opad是一種比特序列,是使用01011100這一比特序列不斷循環(huán)直到分組長度的比特序列。o是outer的意思。
填充后的密鑰和opad XOR計(jì)算后的值稱為 opadkey。 -
與散列值合并
將第4步計(jì)算的散列值拼接在opadkey后面。 -
計(jì)算散列值
將第6步組合后的值進(jìn)行hash,計(jì)算出的散列值就是MAC值。
對消息認(rèn)證碼的攻擊
-
重放攻擊
- 攻擊者可以截獲發(fā)送者的請求消息和MAC值,然后對接收者重放發(fā)送。這時(shí)雖然攻擊者沒有破解消息認(rèn)證碼,但對于接收者來說消息和MAC值是匹配的,所以只能執(zhí)行。
- 解決的辦法。
- 序號。增加一個(gè)流水號,每次都加1。有效果,但是通信雙方都需要記錄最后一個(gè)消息的序號。
- 時(shí)間戳。發(fā)送消息中包含當(dāng)前時(shí)間,如果收到以前的消息則當(dāng)做錯(cuò)誤消息不執(zhí)行。有效果,但是通信雙方的時(shí)鐘必須一致,不一致也會留下重放攻擊的空間。
- nonce。先發(fā)送一個(gè)偽隨機(jī)數(shù)(稱為nonce),然后發(fā)送消息計(jì)算MAC值時(shí)包含nonce。由于每次通信nonce都會發(fā)生變化,也就無法進(jìn)行重放攻擊。此辦法的缺點(diǎn)是增加了通信量。
-
密鑰推測攻擊
如果是單向散列函數(shù)來進(jìn)行生成MAC,則使用攻擊單向散列函數(shù)的暴力破解和生日攻擊來完成攻擊。
消息認(rèn)證碼無法解決的問題
-
對第三方認(rèn)證
如果接收者想要讓第三方來認(rèn)證發(fā)送者,這點(diǎn)是沒法辦到的。因?yàn)楣蚕砻荑€只有一個(gè),對于第三方來說無法通過共享密鑰來判斷到底哪個(gè)是發(fā)送者,哪個(gè)是接收者。 -
防止否認(rèn)
假設(shè)發(fā)送者否認(rèn)自己沒有發(fā)送消息,