什么是消息验证码 MAC?
有两个人 A 和 B。 A 通过网络向 B 发送一条消息。B 收到了之后,怎么确认:
1,这条消息没有被中间人篡改过
2,这条消息确实来自于 A,而不是某个 C 伪造出来的
答案就是使用 MAC。A 在发送消息时,计算出该消息的 MAC 值,并将其一起发送给 B。B 收到之后,便可以根据 MAC 确认 1 和 2.
直接出公式:
MAC = 散列 + 对称密钥
也就是说,消息验证码 MAC 是散列技术和对称密钥技术的联合使用。
首先说散列,散列的作用是防篡改。
任何一段消息,不管有多长,都可以通过一个散列算法计算出一个固定长度的散列值。常用的散列算法是 md5 和 sha 系列。
散列算法的特点是:
1,结果是固定长度
2,计算速度非常快
3,只要两条消息的内容不一样(哪怕只有一个 bit 不一样),其散列的结果一样的概率极低极低(不是完全没有)
4,极其难以从散列值反向推导出消息的内容
散列怎么做到防篡改的呢?
我们在网上下载文件的时候,很多网站会在下载链接旁边展示该文件的散列值和所采用的散列算法。我们下载完成后,用一样的算法对文件内容计算一次散列值,然后和网站上的散列值比对一下,如果一样,则可以断定文件在下载过程中没有被中间人篡改过。因为如果有一个攻击者 C,在中间拦截了文件,并做了手脚,然后再发送给我们的话,文件的散列值就会变 (根据散列算法的特点3)。那我们比对的时候就会发现不一样。
接下来说密钥。密钥的作用是身份验证。
在下载文件的场景下,散列就足够了。可是在文章开头的例子中,A 向 B 发消息,仅仅用散列还不够,为什么呢?
因为 B 无法提前知道消息的散列值。
你可能会问,如果 A 在发送每条消息的时候,都把散列值一起发送给 B,B 收到后再逐条比对,可不可以呢?不可以,因为如果有攻击者 C 的话,消息和散列值会被一起拦截,一起替换。C 改掉消息内容之后,顺便把散列值也更新一下,再发送给 B,B 是不能发现任何问题的。
于是密钥就出场了。
B 无法提前知道消息的散列值,但是 A 和 B 可以提前商量好一个密钥 K,分别秘密保存一份。A 发每条消息的时候,也一并发送一个散列值,但这个散列值不是单纯消息的散列值,而是把消息和密钥进行拼接,然后再对拼接的结果进行散列(这里做了简化,实际复杂一些,但原理一样)。
现在再假设有攻击者 C,他拦截到消息和散列值,然而却无法对消息进行篡改,因为他不知道密钥是什么,无法计算出新的散列值。他也无法推测出密钥是什么。因为散列算法的特点4。所以,有了带密钥的散列之后,B 就可以同时确认:
1,这条消息没有被中间人篡改过
2,这条消息确实来自于 A,而不是某个 C 伪造出来的
这个带密钥的散列值,就是消息验证码 MAC。