消息认证码说明
作用对消息进行认证并确认其完整性的技术,但不能保证消息的机密性
原理使用发送者和接收者之间共享的密码,识别是否存在伪装或篡改
实用技术单向散列函数和对称加密技术
存在问题由于收发双方共享相同密钥,因此无法对第三方证明以及无法防止否认

认证加密是将消息认证码与对称加密相结合,同时满足消息机密性、完整性以及认证三大功能。

由于使用对称密码,发送者和接收者均可以生成消息认证码,因此对于第三方来说无法证明消息是由发送者生成的,即消息认证码无法防止否认

消息认证码

消息特性说明
完整性判断消息在传递过程中是否被篡改
认证判断消息是否来自正确的发送者,是否被伪装

介绍

术语说明
消息认证码(Message Authentication Code)一种确认完整性并进行认证的技术,简称MAC
输入任意长度的消息和一个收发双方共享的密钥
输出固定长度的数据,称为MAC值

使用收发双方的共享密钥来完成认证(没有密钥的人无法计算MAC值);使用MAC值来确认消息完整性。

消息认证码是一种于密钥相关联的单向散列函数。

步骤

sequenceDiagram     participant 发送者     participant 接收者     autonumber     发送者 ->> 接收者: 共享密钥     发送者 ->> 发送者: 使用密钥和消息计算MAC值     发送者 ->> 接收者: 消息+MAC值     接收者 ->> 接收者: 使用密钥和消息计算MAC值     接收者 ->> 接收者: 对比计算得到的MAC值和接收的

如果两个MAC值相同,则发送者通过认证;如果不一致,则发送者被伪装。

共享密钥的配送问题可以参考对称加密的密钥配送问题的解决方式。

应用实例

SWIFT

Society for Worldwide Interbank Financial Telecommuncation(环球银行金融电信协会),用于提供信息网络进行通讯并交换标准化金融报文,为国际银行间的交易保驾护航。

银行之间通过SWIFT传递消息,为了确认消息的完整性以及对消息进行验证,SWIFT中使用了消息认证码。

在使用公钥密码进行密钥交换之前,消息认证码所使用的共享密钥是由人来进行配送的。

IPsec

IPsec是对IP协议增加安全性的一种方式。

在IPsec中,对通信内容的认证和完整性校验都是采用消息认证码来完成的。

SSL/TLS

实现方法

单向散列函数

使用SHA-之类的单向散列函数可以实现消息认证码,其中一种实现方法称为HMAC

分组密码

使用AES之类的分组密钥可以实现消息认证码。

  1. 分组密码的密钥作为消息认证码的共享密钥。
  2. 使用CBC模式将消息全部加密。
  3. 将除最后一个分组的密文部分用作MAC值,其他全部丢弃(消息认证码不需要解密)。

CBC模式的最后一个分组会受到整个消息以及密钥的双重影响,可以用作消息认证码。例如AES-CMAC(Information on RFC 4493 » RFC Editor (rfc-editor.org)

其他方法

流密码和公钥密码也可以实现消息认证码。

认证加密

认证加密是一种将对称密码与消息认证码相结合,同时满足机密性、完整性和认证三大功能的机制。

Encrypt-then-MAC

先用对称密码将明文加密,然后计算密文的MAC值。

消息认证码的输入消息是密文,通过MAC值来进行认证;通过对称加密来确保机密性和完整性。

Encrypt-and-MAC

将明文用对称密码加密,并且对明文计算MAC值。

MAC-then-Encrypt

先计算明文的MAC值,然后将明文和MAC值一起用对称密码加密。

GCM与GMAC

GCM(Galois/Counter Mode)也是一种认证加密方式。

GCM中使用AES 128比特分组密码的CTR模式,并使用一个反复进行加法和乘法的散列函数来计算MAC值。

CTR模式本质上是对递增的计数器值进行加密,因此可以通过对若干个分组进行并行处理来提高运行速度。

CTR模式加密与MAC值的计算使用相同的密钥,在密钥管理方面比较容易。

专门用于消息认证码的GCM称为GMAC。

HMAC

HMAC是一种使用单向散列函数来构造消息认证码的方法(Information on RFC 2104 » RFC Editor (rfc-editor.org))。

HMAC中所使用的单向散列函数并没有限制,任何可靠的单向散列函数都可以被使用。

使用SHA-1、SHA-224、SHA-256、SHA-384、SHA-512构造的HMAC,名称分别为HMAC-SHA-1、HMAC-SHA-224、HMAC-SHA-256、HMAC-SHA-384、HMAC-SHA-512。

步骤

1、密钥填充

if 输入密钥长度 < 单向散列函数分组长度:
    末尾填充0, 直到长度=单向散列函数分组长度
else
    call 单向散列函数(输入密钥): 获得单向散列函数分组长度密钥(用作HMAC密钥)

2、填充后的密钥与ipad的XOR

将填充后的密钥与被称之为ipad的比特序列进行XOR运算。

术语说明
ipad00110110(16进制的36)比特序列不断循环反复直到达到分组长度所形成的比特序列。
ipadkeyXOR运算得到的值,一个和单向散列函数的分组长度相同,且和密码相关的比特序列。

3、与消息组合

将和密钥相关的比特序列(ipadkey)附加在消息的开头。

4、计算散列值

将步骤3的输出结果作为单向散列函数的输入,计算散列值。

5、填充后的密钥与opad的XOR

将填充后的密钥与被称之为opad的比特序列进行XOR运算。

术语说明
opad01011100(16进制的5C)比特序列不断循环反复直到达到分组长度所形成的比特序列。
opadkeyXOR运算得到的值,一个和单向散列函数的分组长度相同,且和密码相关的比特序列。

6、与散列值组合

将步骤4的散列值拼在opadkey后面。

7、计算散列值

将步骤6的结果输入单向散列函数,并计算出散列值,作为最终的MAC值。

攻击

重放攻击

攻击者将截取到的MAC值和消息不断发送给接收者,使接收者不断接收到消息,执行相应的动作,这种行为叫做重放攻击。

序号

收发双方可以对每次发送的消息赋予一个递增的编号,并且在计算MAC值时将序号也包含在消息中。

攻击者无法计算序号递增之后的MAC值,因此可以防御重放攻击。缺点在于,通讯双方需要记录最后一个消息的序号。

时间戳

约定在发送消息时包含当前的时间,如果受到以前的消息,即便MAC值正确也将其当作错误消息来处理。

由于通信延迟,必须在时间的判断上留下缓冲,因此在这个缓冲的时间段内,还是可以实施重放攻击的。

nonce

通信之前,接收者先向发送者发送一个一次性的随机数,这个随机数称为nonce。发送者在消息中包含这个nonce并计算MAC值。

每次通信时nonce的值都会发生变化,因此无法进行重放攻击。

遗留问题

对第三方证明

防止否认

生成消息认证码时使用的是对称密码,发送者与接收者均可以生成消息认证码,那么对于第三方来说无法判别该消息是否由发送者生成的。

当发送者发送消息之后,否认自己发送过该条消息,那么就没有任何证据可以证明该条消息是由发送者发送的。