这一篇主要是对消息认证码(MAC)和AEAD的介绍,涵盖一些常见模式的原理和结构,其中在MAC算法中主要对HMAC进行介绍,并从AE到AEAD的整个过程对AEAD进行介绍。

基本概念

信息安全三大属性

在MAC与AEAD前,先看一下信息安全的三大属性,而如果保证信息传输过程中信息符合这三大性质,正是MAC和AEAD设计的出发点。

  1. 机密性

机密性意味着对信息实施了必要的安全措施,阻止未授权的访问和泄露,也包括保护个人隐私、敏感数据等。机密性(confidentiality)确保在数据处理的每一个交叉点上都实施了必要级别的安全保护并阻止未经收取授权的信息披露。在数据存储到网络内部的系统和设备上时、数据传输时以及数据到达目的地之后,这种级别的保密都应该发挥作用。

  1. 完整性

完整性意味着对信息实施了必要的安全措施,阻止未授权的篡改和破坏,也包括信息的不可否认性和真实性。完整性(integrity)指的是保证信息和系统的准确性和可靠性,并禁止对数据的非授权更改。硬件、软件和通信机制必须协同工作,才能正确地维护和处理数据,并且能够在不被意外更改的情况下将数据移动至预期的目的地。应当保护系统和网络免受外界的干扰和污染。

  1. 可用性

可用性意味着对信息实施了必要的安全措施,使得信息和系统能够被授权实体可靠、及时的访问到。可用性(availability)保护确保授权的用户能够对数据和资源进行及时的和可靠的访问。网络设备、计算机和应用程序应当提供充分的功能,从而能够在可以接受的性能级别以可预计的方式运行。

消息认证码(MAC)

消息认证码(MAC)是指通过以某种形式对信息应用密码密钥而派生的一种身份验证机制,其并不使用对称密钥来加密信息,是保证消息数据完整性的一种工具。构造方法由M.Bellare提出,安全性依赖于Hash函数,故也称带密钥的Hash函数。消息认证码是基于密钥和消息摘要所获得的一个值,可用于数据源发认证和完整性校验。

在发送数据之前,发送方首先使用通信双方协商好的散列函数计算其摘要值。在双方共享的会话密钥作用下,由摘要值获得消息验证码。之后,它和数据一起被发送。接收方收到报文后,首先利用会话密钥还原摘要值,同时利用散列函数在本地计算所收到数据的摘要值,并将这两个数据进行比对。若两者相等,则报文通过认证

在安全性方面,一个安全的 MAC 算法要满足三个条件:抗碰撞性;消息认证码在其空间内均匀分布;消息验证码的一个或一些比特不能弱于其他比特。满足以上三个条件的消息验证码能够防止穷举搜索攻击,攻击者也无法成功伪造一个消息验证码。

MAC一般有三种基本类型:

  • HMAC散列MAC
  • CBC-MAC
  • CMAC

AEAD

认证加密(Authenticated encryption,AE)和带有关联数据的认证加密(authenticated encryption with associated data,AEAD,AE的变种)是一种能够同时保证数据的保密性、 完整性和真实性的一种加密模式。

HMAC

HMAC,散列消息鉴别码,是基于密钥的 Hash 算法的认证协议。密钥相关的哈希运算消息认证码,HMAC运算利用哈希算法,以一个密钥和一个消息为输入,生成一个消息摘要作为输出。 HMAC算法是基于信息摘要算法的。目前主要集合了MD和SHA两大系列消息摘要算法。其中MD系列的算法有HmacMD2、HmacMD4、HmacMD5三种算法;SHA系列的算法有HmacSHA1、HmacSHA224、HmacSHA256、HmacSHA384、HmacSHA512五种算法。

HMAC算法除了需要信息摘要算法外,还需要一个密钥。HMAC的密钥可以是任何长度,如果密钥的长度超过了摘要算法信息分组的长度,则首先使用摘要算法计算密钥的摘要作为新的密钥。一般不建议使用太短的密钥,因为密钥的长度与安全强度是相关的。通常选取密钥长度不小于所选用摘要算法输出的信息摘要的长度。

HMAC的实现原理是,用公开函数和密钥产生一个固定长度的值作为认证标识,用这个标识鉴别消息的完整性。使用一个密钥生成一个固定大小的小数据块,即MAC,并将其加入到消息中,然后传输。接收方利用与发送方共享的密钥进行鉴别认证等。

这种结构的主要作用是:

  • 不用修改就可以使用适合的散列函数,而且散列函数在软件方面表现的很好, 并且源码是公开和通用的。
  • 可以保持散列函数原有的性能而不致使其退化。
  • 可以使得基于合理的关于底层散列函数假设的消息鉴别机制的加密强度分析 便于理解。
  • 当发现或需要运算速度更快或更安全的散列函数时,可以很容易的实现底层 散列函数的替换。

定义 HMAC 需要一个加密用散列函数(表示为H)和一个密钥K。我们假设H是一个将数据块用一个基本的迭代压缩函数来加密的散列函数。我们用B来表示数据块的字长。(以上提到的散列函数的分割数据块字长B = 64),用L来表示散列函数的输出数据字长(MD5中L=16, SHA-1中L=20)。鉴别密钥的长度可以是小于等于数据块字长的任何正整数值。应用程序中使用的密钥长度若是比B大,则首先用使用散列函数H作用于它,然后用H输出的L长度字符串作为在HMAC中实际使用的密钥。一般情况下,推荐的最小密钥K长度是L个字长。(与H的输出数据长度相等)。HAMC相关概念如下:

H:hash算法,比如(MD5,SHA-1,SHA-256
B:块字节的长度,块是hash操作的基本单位。这里B=64
L:hash算法计算出来的字节长度。(L=16 for MD5, L=20 for SHA-1)。
K:共享密钥,K的长度可以是任意的,但是为了安全考虑,还是推荐K的长度>B。当K长度大于B时候,会先在K上面执行hash算法,将得到的L长度结果作为新的共享密钥。 如果K的长度<B, 那么会在K后面填充0x00一直到等于长度B。
text: 要加密的内容
opad:外部填充常量,是 0x5C 重复B次。
ipad: 内部填充常量,是0x36 重复B次。
XOR: 异或运算。

计算 ‘text’ 的 HMAC公式:

H (K XOR opad, H (K XOR ipad, text))

具体计算步骤如下:

  1. 在密钥 K 后面添加 0 来创建一个子长为 B 的字符串。(例如,如果 K 的字长是 20 字节,B=60 字节,则 K 后会加入 44 个零字节0x00)
  2. 将上一步生成的 B 字长的字符串与 ipad 做异或运算
  3. 将数据流 text 填充至第二步的结果字符串中
  4. 用 H 作用于第三步生成的数据流
  5. 将第一步生成的 B 字长字符串与 opad 做异或运算
  6. 再将第四步的结果填充进第五步的结果中
  7. 用 H 作用于第六步生成的数据流,输出最终结果

其中,用于HMAC的密钥可以是任意长度(比 B 长的密钥将首先被 H 处理)。但当密钥 长度小于 L 时,会降低函数的安全强度。长度大于 L 的密钥也是可以的,但额外的长度并不能显著的提高函数的安全强度。
密钥必须随机选取(或使用强大的基于随机种子的伪随机生成方法),并且要周期性的更新。目前的攻击没有指出一个有效的更换密钥的频率,因为那些攻击实际上并不可行。然而,周期性更新密钥是一个对付函数和密钥所存在的潜在缺陷的基本的安全措施,并可以降低泄漏密钥带来的危害。

HMAC的一个典型应用是用在“挑战/响应”(Challenge/Response)身份认证中,认证流程如下:

  1. 先由客户端向服务器发出一个验证请求。
  2. 服务器接到此请求后生成一个随机数并通过网络传输给客户端(此为挑战)。
  3. 客户端将收到的随机数提供给ePass,由ePass使用该随机数与存储在ePass中的密钥进行HMAC-MD5运算并得到一个结果作为认证证据传给服务器(此为响应)。
  4. 与此同时,服务器也使用该随机数与存储在服务器数据库中的该客户密钥进行HMAC-MD5运算,如果服务器的运算结果与客户端传回的响应结果相同,则认为客户端是一个合法用户

从AE到AEAD

AEAD 产生的原因很简单,单纯的对称加密算法,其解密步骤是无法确认密钥是否正确的。也就是说,加密后的数据可以用任何密钥执行解密运算,得到一组疑似原始数据,而不知道密钥是否是正确的,也不知道解密出来的原始数据是否正确。

因此,需要在单纯的加密算法之上,加上一层验证手段,来确认解密步骤是否正确。

简单地把加密算法和认证算法组合,可以实现上述目的,并由此产生了几个方案:

第一种方案,EtM (Encryption then MAC)

首先对明文进行加密,然后根据得到的密文生成消息认证码(MAC)。密文和它的MAC一起发送。例如IPsec。EtM是ISO/IEC 19772:2009规定的六种认证加密方法中的一种。这是唯一可以达到认证加密安全性最高定义的方法,但这只有在使用的MAC“强不可伪造”时才能实现。

第二种方案,E&M (Encryption and MAC)

同时对原始数据执行加密和MAC运算,把二者拼接起来,发给接收方。接收方先进行解密,然后对解密结果执行 MAC 运算,比对发来的 MAC,验证正确性。用于例如SSH。E&M方法本身并未被证明是“强不可伪造”的。

第三种方案,MtE (MAC then Encryption)

与 EtM 相反,MtE 基于明文生成MAC,然后将明文和MAC一起加密以基于两者生成密文。密文(包含加密的MAC)被发送。MtE方法本身并未被证明是“强不可伪造”的。用于例如SSL/TLS。尽管有理论上的安全性,但对SSL/TLS进行更深入的分析将保护模型化为MAC-then-pad-then-encrypt,即明文先填充到加密函数的块大小。填充错误通常会导致接收方发现可检测到的错误,从而导致Padding oracle attack,如Lucky Thirteen attack

从 2008 年起,业内开始提出,需要在一个算法在内部同时实现加密和认证。基于这个思想,一些新的算法被提出,这些算法被称为真正的 AEAD 算法。其中,常见的 AEAD 算法如下:

  • AES-128-GCM
  • AES-192-GCM
  • AES-256-GCM
  • ChaCha20-IETF-Poly1305
  • XChaCha20-IETF-Poly1305

参考

  1. 什么是AEAD
  2. wiki-认证加密