AES(Advanced Encryption Standard)密码算法的原理性介绍请参考密码、安全方面的资料,本文是参照《密码编码学与网络安全——原理与实践》上面介绍的方案实现的。AES密码有两种基本的实现方案:一种是标准的加/解密方案;另外一种是其变形形式,对解密过程重新设计,使解密算法与加密算法流程一致。第二种方案方便了密码算法的实现,但需要额外地对解密算法使用的轮密钥进行逆向列混淆变换。本文实现的AES采用第二种方案,针对该方案分析密码算法各阶段的实现方法,并给出最终的算法实现。
AES算法在具体实现时,并不是完全按照标准流程进行的。从加/解密性能方面考虑,需要预先计算一些变换,并保存下来,在节约计算时间的同时却增加了密码算法的空间大小(用空间换时间)。
本AES实现使用了4个大小为256的int32数组(te1, te2, te3, te4)来完成字节代换和列混淆的混合运算(同样,对于逆向运算也存在4个这样的数组(td1, td2, td3, td4));使用了4个大小为256的int32数组(imc1, imc2, imc3, imc4)来实现单独的逆向列混淆运算(用于解密算法的轮密钥生成);还有两个大小为256的int8数组,用于字节代换和逆向字节代换的S盒(sbox)和逆S盒(isbox)。还有一个用于生成轮密钥的轮常量数组(rcon)。这些数组占用的空间不到13K大小。可以根据具体应用进行修改,用算法变换代替数组变换可能会节约一些空间,但相应地增加了计算时间。 注:
(1)对于计算轮密钥中使用的逆向列混淆变换,可以使用相应的逆向列变换算法来代替这里的四个数组,从而可以节约4K的空间。并且,由于逆向列变换在该AES实现中只在轮密钥生成中使用,换成算法实现后不会对加/解的性能产生大的影响。
(2)轮常量的周期为51(可由前52个产生的轮常量知),并且在该AES算法中最多只用到
前14个轮常量。
本AES实现支持的工作模式包括:ECB, CBC, CFB, OFB, CTR。在实现时,是在一个函数同时支持这些工作模式的,可以根据需要拆分成相应的函数单独实现。
本AES实现支持的密钥长度为128位/ 192位/256位,支持的基本块大小为128位。
另外,有可能发生这种情况:加密/解密的字符串指针指向同一地址(重复利用空间),这也是被算法所允许的。因此,算法也必须对这种情况做相应处理。处理代码是在encrypt和decrypt中进行的,在所有可能出现的地方都用了临时空间(一个基本块大小)来进行输入的暂存,从而防止了输入/输出地址相同时可能出现的问题。(注意,这里没有检查是否这种情况的发生,而是假设发生并进行处理)。您可以根据自己的需要来改写,比如,进行检查,不同情况进行不同的处理(此时会增长代码量,但效率相对提高)。
本AES实现除了支持基本块的整数倍的数据块的加密外,还支持任意长度的数据的加密,此时需要额外的一个或者两个基本块空间(先将最后的数据块进行填充,再用一个块记录最后一个数据块中的有效字节数)。在加密任意长的数据块之前,可以先调用成员函数获取目标空间的大小(提供了实现该按钮承认成员函数)。
本文的实现环境为VC6,算法实现中使用了VC的扩展类型(__int32),因此,你在使用时可根据具体应用平台换成相应的32位整型类型即可。涉及两个工程:工程AesArrays用来产生最终的AES算法所需要的各种变换数组,也实现了算法的标准流程中的各阶段算法;工程AesCipher实现最终的AES算法,它使用了AesArays中生成的数组数据。另外,在AesCipher中,提供了一个工具类Base64实现Base64编码,以方便测试。 2007-08-06
今天发现一个小的问题,就是生成数据时,把所有u32_t的数据类型输出成了unsigned char
(那个函数本来开始只针对unsigned char类型,后来写成了模板以用于u32_t,但却忘了相应修改输出),现在修正了 2007-08-20
(1)修正了原算法中存在的Bug(来自于AesArrays项目,从而带进了AES-Simple-Variant项目),本次修改对生成的数据进行了严格的验证。
(2)对密码算法进行了修改,默认情况下禁用了原来的imc1, imc2, imc3, imc4四个数组(其占用了4K内存空间),用相应的函数来代替数组参与运算(注:这些数组是由该函数预计算得到的)。当然,节省了内存空间,性能略有下降。事实上,其影响是很小的,因为该函数(或者数组)只在生成轮密钥时使用,当加密的数据量大时,其对性能的影响可忽略不计。如果你不在乎内存空间的使用,可以定义宏开关(__AES_IMC_SPEEDUP__)重新编译,从而使用数组而不是函数
因篇幅问题不能全部显示,请点此查看更多更全内容