赞
踩
消息认证码是密码学家工具箱中6个重要的工具之一。回忆一下,这6个重要的工具分别是:对称密码、公钥密码、单向散列函数、消息认证码、数字签名和伪随机数生成器。
消息认证码(Message Authentication Code)是一种确认完整性并进行认证的计算,取三个单词的首字母,简称MAC。
根据任意长度的消息输出固定长度的数据,这一点和单向散列函数很类似。但是单向散列函数中计算散列值时不需要密钥,相对地,消息认证码中则需要使用发送者与接收者之间共享的密钥。
要计算MAC必须持有共享密钥,没有共享密钥的人就无法计算MAC值,消息认证码正是利用这一性质来完成认证的。此外,和单向散列函数的散列值一样,哪怕消息中发生1比特的变化,MAC值也会产生变化,消息认证码正是利用这一性质来确认完整性的。
由于消息认证码中必须使用到密钥,所以也会出现密钥配送问题。与对称加密一样,密钥配送可以使用公钥密码、DH密钥交换等。
使用 SHA-2 之类的单向散列函数可以实现消息认证码,例如 HMAC。HMAC 中的 H 是 Hash 的意思。可以参考 RFC2104
任何高强度的单向散列函数都可以被用于 HMAC 中,例如 SHA-1、SHA-224、SHA-256、SHA-384、SHA-512 所构造的 HMAC,分别称为 HMAC-SHA1、HMAC-SHA-224、HMAC-SHA-256、HMAC-SHA-384、HMAC-SHA-512。
如果密钥比单向散列函数的分组长度要短,就需要在末尾填充 0,使最终长度和单向散列函数分组长度一样。
如果密钥比分组长度要长,则要用单向散列函数求出密钥的散列值,然后把这个散列值作为 HMAC 的密钥。
将填充后的密钥和 ipad 的比特序列进行 XOR 计算。ipad 是 00110110 (16进制的 36)不断循环直到长度和分组长度一样长的比特序列。ipad 的 i 是 inner 内部的意思。
XOR 得到的最终结果是一个和单向散列函数的分组长度相同,且和密钥相关的比特序列。这个序列称为 ipadkey。
把 ipadkey 附加在消息的开头。
把第 3 步的结果输入单向散列函数,计算出散列值。
将填充后的密钥和 opad 的比特序列进行 XOR 计算。opad 是 01011100 (16进制的 5C)不断循环直到长度和分组长度一样长的比特序列。opad 的 o 是 outer 外部的意思。
XOR 得到的最终结果是一个和单向散列函数的分组长度相同,且和密钥相关的比特序列。这个序列称为 opadkey。
把 opadkey 附加在散列值的开头。
把第 6 步的结果输入单向散列函数,计算出散列值。这个散列值即为最终 MAC 值。
最终的 MAC 值一定是一个和输入消息以及密钥都相关的长度固定的比特序列。
使用 AES 之类的分组密码可以实现消息认证码。分组密码的密钥作为共享密钥,利用 CBC 模式将消息全部加密。由于消息认证码中不需要解密,所以可以只留下最后一个分组,其他分组全部丢弃。CBC 模式的最后一个分组会受到整个消息以及密钥的双重影响,所以它可以作为 MAC 值。AES-CMAC (RFC4493) 就是一种基于 AES 来实现的消息认证码。
使用流密码和公钥密码。
2000 年以后,人们基于认证的研究更加进一步,产生了认证加密 (AE:Authenticated Encryption,AEAD:Authenticated Encryption with Associated Data)。认证加密是一种将对称密码和消息认证相结合的技术,同时满足加密性,完整性和认证性三大功能。
认证加密有几种,这里举例:例如 Encrypt-then-MAC,先用对称密码将明文加密,然后计算密文的 MAC 值。Encrypt-and-MAC,将明文用对称密码加密,并对明文计算 MAC 值。MAC-then-Encrypt,先计算明文的 MAC 值,然后将明文和 MAC 值同时用对称密码加密。在 HTTPS 中,一般使用 MAC-then-Encrypt 这种模式进行处理。
GCM(Galois/Counter Mode)是一种认证加密方式。GCM 中使用 AES 等 128 位比特分组密码的 CTR 模式,并使用一个反复进行加法和乘法运算的散列函数来计算 MAC 值。CTR 模式加密与 MAC 值的计算使用的是相同密钥,所以密钥管理很方便。专门用于消息认证码的 GCM 成为 GMAC。GCM 和 CCM (CBC Counter Mode) 都是被推荐的认证加密方式。
GCM相当于CTR+GMAC,具体方式如下所示:
ChaCha20-Poly1305 是谷歌发明的一种算法,使用 ChaCha20 流密码进行加密运算,使用 Poly1305 算法进行 MAC 运算。
窃听者不直接破解消息认证码,而是把它保存起来,反复利用,这种攻击就叫做重放攻击(replay attack)。
防止重放攻击可以有 3 种方法:
序号
每条消息都增加一个递增的序号,并且在计算 MAC 值的时候把序号也包含在消息中。这样攻击者如果不破解消息认证码就无法计算出正确的 MAC 值。这个方法的弊端是每条消息都需要多记录最后一个消息的序号。
时间戳
发送消息的时候包含当前时间,如果收到的时间与当前的不符,即便 MAC 值正确也认为是错误消息直接丢弃。这样也可以防御重放攻击。这个方法的弊端是,发送方和接收方的时钟必须一致,考虑到消息的延迟,所以需要在时间上留下一定的缓冲余地。这个缓冲之间还是会造成重放攻击的可趁之机。
nonce
在通信之前,接收者先向发送者发送一个一次性的随机数 nonce。发送者在消息中包含这个 nonce 并计算 MAC 值。由于每次 nonce 都会变化,因此无法进行重放攻击。这个方法的缺点会导致通信的数据量增加。
消息认证码同样可以暴力破解以及生日攻击。消息认证码必须要保证不能通过 MAC 值推测出通信双方所使用的密钥。这一点可以通过单向散列函数的单向性和抗碰撞性来保证无法推测出密钥。
消息认证码虽然可以证明双方发送的消息是一致的,没有篡改,也不存在中间人伪装。但是它无法 “对第三方证明” 和 “防止抵赖”。无法 “对第三方证明” 原因是因为消息认证码中用到的密钥是共享密钥,通信双方都有这个密钥,所以对第三方无法证明消息到底出自双方中的哪一方。
解决 “第三方证明” 的问题需要用到数字签名。
无法 “防止抵赖” 原因是也是因为消息认证码的共享密钥双方都有,无法判断消息是发自于哪一方。所以消息认证码无法防止否认(nonrepudiation)。
解决 “防止抵赖” 的问题需要用到数字签名。
该系列的主要内容来自《图解密码技术第三版》
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。