一、EAX简介
认证加密(AE)方案是一种通过消息M转换成密文CT为目标,保护M的隐私和真实性的对称密钥机制。近几年来,AE的出现成为公认的密码目标。认证加密方案,EAX,提供了一种基于认证加密的机制。
介绍EAX之前,先简单介绍一下OMAC。OMAC是一种基于块加密的消息认证,OMAC允许任意长度的消息,CBC MAC仅仅对于固定长度且是块长度的倍数的消息是安全的。CMAC是效率是高度优化的,与CBC MAC一样高效。OMAC是OMAC1和OMAC2的统称。下图是OMAC1和OMAC2的算法流程:
OMAC1算法流程分为预处理过程和Tag的生成。
预处理过程:
生成n位的0,让0 n 与K(加密密钥)做E (K, 0 n) 加密运算,生成L。若L的最高位是0,则左移一位,将最高位移出,低位最后一位补0。否则让次高位异或一个n位的常量,如下图3所示。如果n是128位则这个常量是0x00000000000000000000000000000087,如果n是64位则这个常量是0x000000000000001b。本文的代码中采用的是128位的常量,如下图4所示。上述操作后的的L命名为L.u,检验L.u的最高位,若为0则左移一位,否则,左移一位后与0x00000000000000000000000000000087这个常量异或操作,如下图5所示。
Tag的生成:
将消息M分为M[1], M[2], ..., M[m],其中M[i] (i = 1 ,..., m-1)是n位,M[m]可能是n位或者比n位少。 生成n位的0记为Y[0],对于i从1到m-1让K,M[i],Y[i-1]做E(K, M[i] xor Y[i-1]) 运算.,如下图6所示。若M[m]即M_last长度等于n时,则让M[m] xor Y[m-1] xor L.u ;否则先填充,然后做M[m] xor Y[m-1] xor L.u 2 运算。如图7中所示:
在双路机制中,我们通过数据提供双路认证,致力于提供加密和认证。通过类属成分提供的双路认证,一路用于构成隐私的加密机制,另一路是消息认证码(MAC)。加密和认证使用它们各自的一把私钥(这一点很重要哦)。EAX是一种使用随机数的AEAD模式,AEAD是基于区块的加密模式。nonce只要不重复即可,EAX提供了隐私和认证,使得攻击方不能生成新的并且有效的nonce+header+ciphertext(随机数+头部+密文)。EAX在功能上是灵活多变的,它支持任意长度的消息,也支持任意长度的nonce,任意长度的tag(认证码)都是有可能的,这样能够允许用户根据安全度选择他想要的安全级别。EAX的安全性意味着不可区分的随机位和认证码,因此安全级别极高。下图是EAX的认证流程,详细介绍可以参考:http://web.cs.ucdavis.edu/~rogaway/papers/eax.pdf,与这篇参考文献稍有差别是:本篇采用本篇中采用的是CMAC,它是一种基于密文的消息认证码。而下图所采用的是OMAC,但处理流程是类似的。
图8中简单介绍其中N是nonce随机数,H是头部,M是消息体。加密时对N、H、M分别做OMAC0、OMAC1、OMAC2处理,对处理后的结果做一个异或运算得到Tag,然后取Tag的前T位,得到MAC认证码。解密过程类似于加密过程。
二、JS实现EAX介绍
①、项目地址:https://github.com/ying2025/websocket---vbs/blob/master/EAX/eax.js
②、测试地址:https://github.com/ying2025/websocket---vbs/blob/master/EAX/test.js
③、详解
a、文件内主要实现功能介绍:
eax.js主要实现eax算法以及CMAC实现算法;cryptojs-aes.min.js主要实现了AES加密算法;cryptojs-mode-ctr.min.js主要实现了CMAC的CRT模式加密。
b、EAX的实现
在eax.js里面包含了三个立即执行函数,其中包含ext的立即执行函数主要封装和实现了EAX和CMAC的一些函数,接下来主要讲解CMAC和EAX这两个立即执行函数。
CMAC部分:主要包括块加密函数、初始化创建CMAC、认证消息、MAC的生成
aesBlock函数主要实现16字节的块加密
init函数主要使用加密的Key派生出认证的Key即生成MAC的Key,如图10中所示。当是CMAC1算法时,K2的生成采用
var K2 = K1.clone();
ext.dbl(K2);
当采用CMAC2时,K2的生成采用
var K2 = L.clone();
ext.inv(K2);
update函数主要是将M分为M[1],M[2],...,M[m],然后按照块加密方式对其加密,同时计数器累加,流程如图12所示:
EAX部分:初始化块加密对象、以0为初始值,应用CMAC对nonce、header、Msg进行认证计算出最后的消息认证码以及加密或者解密后的数据。
init函数主要使用key初始化加密对象,以及tag;reset函数主要初始化_mac,默认以1为初始值。如图13所示
updateAAD主要应用CMAC对header进行认证;initCrypt函数主要初始化Tag,以0为初始值对nonce认证,认证的结果赋值给nonce,然后作为KCTR加密模块的初始向量,如下图14所示:
update函数实现主要功能:若是加密则数据的长度是buffer的长度,然后对数据进行加密处理;若是解密则数据长度减去tag的长度,然后对数据进行解密处理。其中判断self.xoredData是否等于undefined主要是concat函数使用对象不能为undefined,此处主要为了多个消息可以连续使用update函数
finalize函数主要实现了加密MAC的生成以及最后一块Block的生成,若是加密则密文为前n-1块数据拼接最后一个区块的数据再拼接MAC认证码;否则,前n-1块的数据拼接最后一个区块的数据。
prepareEncryption函数包括对nonce和header分别做CMAC0和CMAC1认证
测试说明:
nodejs里面使用,在test.js文件test2函数,先运行立即执行函数,然后使用KeyBytes初始化eax加密对象,然后使用nonce和header认证nonce和header,然后对数据进行加密和认证,最后生成密文.如图18所示:
注意:使用let msgBytes4 = CryptoJS.lib.WordArray.create(new Uint8Array([12,234,34,23,34,45,34, 67, 89, 89, 23, 89,34,12,34,45]));解密后可能会有多余0,会造成误差,具体可以运行测试类运行试试,使用test2.js里面的test2()的函数你就会发现不一样之处。
三、go实现EAX介绍
①、项目地址:https://github.com/halftwo/mangos/blob/master/eax/eax.go
②、测试地址:https://github.com/halftwo/mangos/blob/master/eax/eax_test.go
测试地址2: https://github.com/ying2025/Server/blob/master/eax/eax_test.go
说明:go实现EAX主要是熊家贵老师实现的,本人在熊家贵老师的基础上对测试类进行了简单封装。
③、详解
a、文件内主要实现功能介绍:
eax.go主要实现eax算法以及CMAC实现算法,还包括一些填充函数。
b、EAX的实现
CmacCtx结构体主要由16字节块加密对象cipher、_X主要用来保存M[m]与Y[i-1]异或的结果,count主要用来计数,主要实现CMAC的CRT模式;NewCmac函数:判断加密块对象是否是16字节的加密块,若是则初始化CmacCtx对象,否则,保存;Start函数:主要用于初始化_X,以0填充_X;blockXOR函数主要实现两个字节数组每一项异或运算。 如下图19、20所示:
Update函数:若是nonce则进行CMAC0认证,若是header则进行CMAC1认证; 若不是,然后让buf的每一项与_X做异或运算,即以之前的值为初始值对其进行CMAC认证。
gf_mulx1和gf_mulx2函数主要用于填充的,如图24中所示的流程图,如23中程序判断部分
Finish函数主要用于完成CMAC认证
EaxCtx结构体主要CMAC对象,加密标志,当前处于一个区块的位置,_S