寫給開發(fā)人員的實用密碼學(xué) - MAC

云水木石
陳正勇
作為更復(fù)雜的KDF函數(shù),我們可以通過使用一些稱為“鹽”的隨機(jī)值計算HMAC(salt,msg,SHA256)來生成密碼,該隨機(jī)值與導(dǎo)出的密鑰一起存儲,以后用于再次從密碼中導(dǎo)出相同的密鑰。

這里的MAC,并不是計算機(jī)中的MAC地址,而是消息驗證碼(Message Authentication Code,MAC)。在寫給開發(fā)人員的實用密碼學(xué)-Hash算法中講到的Hash算法能夠進(jìn)行完整性校驗,但卻不能避免消息被篡改,而MAC正是為了避免消息被篡改而設(shè)計。

為什么需要MAC

在寫給開發(fā)人員的實用密碼學(xué)-Hash算法這篇文章中,談到密碼學(xué)哈希算法用途之一就是保證文檔/消息完整性。對于文件下載來說,通過計算下載下來的文件的Hash值,和網(wǎng)站提供的Hash值進(jìn)行對比,就能確定下載下來的文件是否和網(wǎng)站上的原始文件一致。這對于一些固定的使用場景有效(網(wǎng)站提供下載的文件比較固定),如果是任意消息(文檔)的發(fā)送,怎么提供原始消息(文檔)的Hash值呢?一個比較容易想到的方法是將Hash值附在消息的后面,一起發(fā)送給接收方,如下圖所示:

2345截圖20200908083720.png

Hash值隨消息一起發(fā)送

接收方校驗Hash值是否和接收到的Hash值相同,看起來沒毛病。但如果考慮到如下的場景呢?

2345截圖20200908083720.png

中間人攻擊

攻擊者對消息進(jìn)行攔截,修改消息,然后計算該消息的摘要值(摘要算法是公開的),附在消息后面發(fā)送給接收方。接收方收到消息后,對消息計算摘要值,然后與接收到的摘要值進(jìn)行比較,并沒有發(fā)現(xiàn)有異常,而實際上接收到的消息已經(jīng)被篡改。

通過對消息加密是一種解決方法。但在很多情況下,傳遞的消息沒有必要加密,只要確保消息是完整且沒有被篡改即可,原因可能如下:

●接口的數(shù)據(jù)并不重要,對隱私性要求不高。

●加密和解密過程很消耗性能。

另一種解決方法是MAC算法。MAC是由給定密鑰和給定消息計算得出的驗證碼:

auth_code=MAC(key,msg)

通信雙方維護(hù)同一個密鑰,只有擁有密鑰的通信雙方才能生成和驗證消息驗證碼。通常,它的行為類似于哈希函數(shù):

●消息或密鑰中的微小變化導(dǎo)致MAC值完全不同。

●更改密鑰或消息并獲得相同的MAC值實際上是不可行的。

●MAC驗證碼像哈希一樣是不可逆的:無法從MAC代碼中恢復(fù)原始消息或密鑰。

MAC算法也稱為“鍵控哈希函數(shù)”,因為它們的行為類似于帶有密鑰的哈希函數(shù)。

MAC值一般和原始消息一起傳輸,原始消息可以選擇加密,也可以選擇不加密,通信雙方會以相同的方式生成MAC值,然后進(jìn)行比較,如下圖所示:

2345截圖20200908083720.png

MAC處理流程

MAC算法的種類

現(xiàn)代密碼學(xué)中存在許多MAC算法。最受歡迎的是基于哈希算法,例如HMAC(基于哈希的MAC,例如HMAC-SHA256)和KMAC(基于Keccak的MAC)。還有的則基于對稱加密,例如CMAC(基于加密的MAC),GMAC(Galois MAC)和Poly1305(Bernstein一次性身份驗證器)。其他MAC算法包括UMAC(基于通用哈希),VMAC(基于高性能分組加密的MAC)和SipHash(簡單、快速、安全的MAC)。

作為開發(fā)人員,我們并不需要了解這么多MAC算法,重點了解HMAC(Hash-based Message Authentication Code)即可,它在SSL/TLS通信中得到廣泛使用。

HMAC算法使用Hash算法作為加密基元,HMAC結(jié)合Hash算法有多種變種,比如HMAC-SHA-1、HMAC-SHA256、HMAC-SHA512,國密標(biāo)準(zhǔn)中則使用SM3 Hash算法。大家不要誤以為HMAC算法就是Hash算法加上一個密鑰,HMAC算法只是基于Hash算法的,內(nèi)部的實現(xiàn)還是相當(dāng)復(fù)雜的,我們通常并不需要了解,現(xiàn)有的加密/解密庫通常已經(jīng)實現(xiàn)了HMAC算法。

MAC算法實例

借助OpenSSL命令行工具,計算HMAC非常容易:

$echo-n abc|openssl dgst-sha256-hmac Passw0rd

(stdin)=c12a3b777eaebdc2f98e79418f605f9b0b23064161e83aa19e3cf37c005181f3

國密標(biāo)準(zhǔn)中使用SM3作為加密基元,也可以通過命令行計算:

$echo-n abc|gmssl dgst-sm3-hmac Passw0rd

(stdin)=db1ab0dda0aafbdcd53cbda95b7ecdee4a50586f92696616ab052aceea106212

MAC算法的用途

MAC算法的主要用途:

證明消息沒有被篡改,這和Hash算法類似。

消息是正確的發(fā)送者發(fā)送的,也就是說消息是經(jīng)過驗證的。

此外MAC算法還可以使用在如下場景。

基于HMAC的密鑰派生(HMAC-based key derivation,HKDF)

密鑰派生功能(KDF)是將可變長度密碼轉(zhuǎn)換為固定長度密鑰(比特序列)的功能:

function(password)->key

一種非常簡單的KDF函數(shù),我們可以使用SHA256:僅對密碼進(jìn)行哈希處理。但不要這樣做,因為它是不安全的,簡單的哈希很容易受到字典攻擊。

作為更復(fù)雜的KDF函數(shù),我們可以通過使用一些稱為“鹽”的隨機(jī)值計算HMAC(salt,msg,SHA256)來生成密碼,該隨機(jī)值與導(dǎo)出的密鑰一起存儲,以后用于再次從密碼中導(dǎo)出相同的密鑰。

基于MAC的偽隨機(jī)發(fā)生器

我們可以從“鹽”(常數(shù)或當(dāng)前日期和時間或其他隨機(jī)性)和種子(上一次生成的隨機(jī)數(shù),例如0)開始,計算next_seed:

next_seed=MAC(salt,seed)

在每次計算上述公式之后,下一個偽隨機(jī)數(shù)將“隨機(jī)更改”,我們可以使用它來生成特定范圍內(nèi)的下一個隨機(jī)數(shù)。

小結(jié)

在本文中我們介紹了消息驗證碼,消息驗證碼彌補(bǔ)了單一的Hash算法的不足,確保消息沒有被篡改。接下來的部分介紹了MAC算法的種類和用途。在下一篇文章中,我們將介紹密碼學(xué)中的隨機(jī)數(shù)產(chǎn)生器!

THEEND

最新評論(評論僅代表用戶觀點)

更多
暫無評論