购买
下载掌阅APP,畅读海量书库
立即打开
畅读海量书库
扫码下载掌阅APP

2.5

消息验证码

本节介绍一个和Hash算法息息相关的算法,这就是消息验证码(Message Authentication Code,MAC)算法。Hash算法能够完成密码学目标之一的完整性校验,但却不能避免消息被篡改,为避免消息被篡改,需要用到消息验证码。消息验证码非常重要,一般结合加密算法一起使用。

2.5.1 什么是消息验证码

在密码学应用中,很多情况下,传递的消息没有必要加密,只要确保消息是完整且没有被篡改即可。比如开发者开发了一组天气API,接口返回的数据并没有加密,原因可能如下:

◎ 接口的数据并不重要,对隐私性要求不高。

◎ 加密和解密过程很消耗性能。

所以接口的设计目标仅仅是避免消息被篡改,读者可能说那很简单啊,接口消息通过Hash算法得到一个摘要值,摘要值和接口消息同时作为接口内容返回不就解决问题了吗?具体的处理逻辑如图2-8所示。

img

图2-8 Hash算法不能解决消息验证(1)

图2-8的逻辑看上去没有问题,接收方校验摘要值是相同的,如果相同是否能够说明消息没有篡改?实际上这种方案存在中间人攻击(后续章节会讲解),具体攻击逻辑如图2-9所示。

通过图2-9可以看出,攻击者对消息进行拦截,同时修改接口消息和消息的摘要值然后发送给接收方,接收方收到消息后,对接口消息计算摘要值,然后与接收到的摘要值进行比较,如果相同,接收方认为消息是完整的。可实际呢?消息虽然是完整的,但被篡改了,或者说消息被伪装了,但对于接收方来说,仅仅通过摘要值无法验证消息是不是篡改了,这时候需要使用MAC算法。

img

图2-9 Hash算法不能解决消息验证(2)

以上例子也充分证明了Hash算法和MAC算法密码学目标是不一样的。

消息验证码算法的特点:

◎ 证明消息没有被篡改,这和Hash算法类似。

◎ 消息是正确的发送者发送的,也就是说消息是经过验证的。

注意,消息验证和身份验证是不同的概念,身份验证会在本章后续部分详细描述。

如何确保消息是特定人发送的呢?在通信双方可以维护同一个密钥,只有拥有密钥的通信双方才能生成和验证消息验证码,消息验证码算法需要一个密钥,这和对称加密算法是一样的,通信双方在消息传递之前需要获得同样的密钥。

消息验证码的模型很简单:

MAC值 = mac(消息,密钥)

MAC值一般和原始消息一起传输,原始消息可以选择加密,也可以选择不加密,通信双方会以相同的方式生成MAC值,然后进行比较,图2-10概括了该过程。

img

图2-10 MAC处理流程

一旦两个MAC值相同表示MAC验证正确,否则验证失败。

2.5.2 MAC算法的种类

在密码学中,MAC算法有两种形式,分别是CBC-MAC算法和HMAC算法。

CBC-MAC算法从块密码算法的CBC分组模式演变而来,简单地说就是最后一个密文分组的值就是MAC值,在HTTP中应用最多的MAC算法是HMAC算法,所以重点讲解HMAC算法。

HMAC(Hash-based Message Authentication Code)算法使用Hash算法作为加密基元,HMAC结合Hash算法有多种变种,比如HMAC-SHA-1、HMAC-SHA256、HMAC-SHA512。

读者不要误以为HMAC算法就是Hash算法加上一个密钥,HMAC算法只是基于Hash算法的,内部的实现还是相当复杂的,接下来用伪代码进行描述。

img

2.5.3 消息验证码算法实践

1)PHP

用一个PHP例子来解释如何使用HMAC算法:

img
img

hash_hmac函数是PHP内置的一个HMAC算法,需要传递两个关键参数,分别是特定Hash算法名称和密钥。

2)OpenSSL

在使用HMAC算法之前,先了解OpenSSL命令行如何操作Hash算法,使用很简单,下面的例子是生成摘要值:

img

2.5.4 加密算法不能提供完整性

讲完对称加密算法和MAC算法后,必须将这两种算法放在一起描述,核心的观点就是加密算法不能提供完整性,加密的同时必须引入MAC算法避免消息被篡改。

加密算法能够解决机密性的问题,比如攻击者虽然能够截获加密数据,但如果没有密钥,则无法得到原文。

完整性的意思是消息没有被篡改,仅仅加密数据是无法保证数据完整性的,初听起来可能觉得很奇怪。攻击者如果没有密钥就无法破解原文,也就无法篡改,数据必然是完整的。遗憾的是攻击者虽然无法破解数据,但是可以修改密文的部分数据,然后发送给接收者,接收者通过密钥发现能够解密,但是解密出来的值实际上不是原文,消息已经被修改了,也就是说加密操作不能提供完整性。

接下来通过一个PHP例子来描述为什么加密不能提供完整性,运行下面的代码最终能够破解密文:

img

示例中的代码会迭代对明文中的每一位进行篡改,如果能够反解成功,表示加密操作虽然能够保证机密性,但不能保证完整性,读者可以运行示例代码了解细节。

截至目前,读者知晓了对称加密算法可以保证消息的机密性,MAC算法可以保证消息的完整性,将两者结合起来,就可以保证消息同时具备机密性和完整性,演示的PHP代码如下:

img

2.5.5 AD加密模式

使用者结合对称加密算法和MAC算法,提供机密性和完整性的模式也叫作Authenticated Encryption(AE)加密模式,主要有三种,简单介绍如下。

1)Encrypt-and-MAC (E&M)

这种模式(图2-11)就是对消息分别进行加密运算和MAC运算,然后将两个运算结果结合起来发送给接收方。

img

图2-11 Encrypt-and-MAC

2)MAC-then-Encrypt (MtE)

这种模式(图2-12)先对消息进行MAC计算,然后将消息和MAC值组合在一起再进行加密,最终的加密值再发送给接收方。在HTTPS中,一般使用这种模式进行处理,比如AES-128-CBC#PKCS7-HMAC-SHA256模式。

3)Encrypt-then-MAC (EtM)

这种模式(图2-13)先对消息进行加密得到密文,然后对密文再计算MAC值,最终将密文和MAC值组合在一起再发送给接收方。

img

图2-12 MAC-then-Encrypt

img

图2-13 Encrypt-then-MAC

不管是Encrypt-and-MAC模式还是MAC-then-Encrypt模式,使用不当的话都会存在安全问题,目前建议使用Encrypt-then-MAC模式。需要强调的是,这三种模式使用者必须分别处理,一旦处理不当,就可能会存在安全风险,那有没有一种方法在底层直接提供加密和MAC运算呢?无须使用者分别处理加密和MAC运算,这就是接下来讲解的AEAD模式。

2.5.6 AEAD加密模式

AEAD(Authenticated Encryption with Associated Data)是AE加密模式的一种变体,AE模式需要使用者单独处理加密运算和MAC运算,一旦使用不当,就很容易出现安全问题。

AEAD加密模式在底层组合了加密算法和MAC算法,能够同时保证数据机密性和完整性,减轻了使用者的负担,主要有三种模式,接下来分别介绍。

1)CCM模式

CCM(Counter with CBC-MAC)模式也是一种AEAD模式,不过在HTTPS中使用得比较少。

这种模式使用CBC-MAC(一种MAC算法)算法保证完整性,使用块密码AES算法CTR模式的一种变种进行加密运算,底层采用的是MAC-then-Encrypt模式。

2)GCM模式

GCM(Galois/Counter Mode)是目前比较流行的AEAD模式。在GCM内部,采用GHASH算法(一种MAC算法)进行MAC运算,使用块密码AES算法CTR模式的一种变种进行加密运算,在效率和性能上,GCM都是非常不错的。

3)ChaCha20-Poly1305

ChaCha20-Poly1305是谷歌发明的一种算法,使用ChaCha20流密码算法进行加密运算,使用Poly1305算法进行MAC运算。 t6sTu+1Hm10QDDVkOXNObo4eL/69GGq/AAdN54UHSuRAn2KArfWcjehWbMUDqhT1

点击中间区域
呼出菜单
上一章
目录
下一章
×