密码学基础 AES算法C语言实现
作为密码学的第一篇blog,首先将字符和位的关系说明清楚:
通常情况下一字节等于八位,通常在读取图片、声音、可执行文件需要用字节数组来保存文件,在下载文件也是用byte数组来做临时的缓冲器接收文件内容。
字符(Character)计算机中使用的字母、数字、字和符号,比如’P’、’K’、’%’、’#’等。
==一般在英文状态下一个字母或字符占用一个字节,一个汉字用两个字节表示。==
- ASCII 码中,一个英文字母(不分大小写)为一个字节,一个中文汉字为两个字节。
- UTF-8 编码中,一个英文字为一个字节,一个中文为三个字节。
- Unicode 编码中,一个英文为一个字节,一个中文为两个字节。
- 符号:英文标点为一个字节,中文标点为两个字节。例如:英文句号 . 占1个字节的大小,中文句号 。占2个字节的大小。
- UTF-16 编码中,一个英文字母字符或一个汉字字符存储都需要 2 个字节(Unicode 扩展区的一些汉字存储需要 4 个字节)。
- UTF-32 编码中,世界上任何字符的存储都需要 4 个字节。
AES简介
是DES的替代算法,同样也是对称加密算法
- 和DES一样,能有效抵御所有已知攻击;
- 加密算法易于现有软硬件平台的实现,且加解密过程效率优于DES;
- 具有典型的对称分组加密算法特性,以快速混淆和扩散为设计原则,本质是轮函数过程的循环。
AES的数据分组长度统一为128位,而密钥空间可根据需要采用128位、192位和256位三种不同长度。和大多数分组加密算法不一样AES的轮函数并没有采用Feistel结构设计,而是使用了3个不同的可逆均匀变换。
AES算法主要步骤
- 密钥扩展(Key Expansion),使用密钥扩展算法将128位用户主密钥扩展成R个轮密钥;
- 初始轮(Init Round),即为轮密钥加;
- 重复轮(Rounds),每一轮包括:字节替换(SubBytes),行移位(Shift Rows),列混合(Mix Columns),轮密钥加(Add Round Key)四个步骤;
- 最终轮(Final Round),最终轮比重复轮少了列混合的步骤。
==最后一轮是不用列混合操作的==
AES算法具体内容
在讲述密钥加法层之前,我们来看看密钥的扩展
密钥扩展
子密钥的生成是以列为单位进行的,一列是32Bit,四列组成子密钥共128Bit。生成子密钥的数量比AES算法的轮数多一个,因为第一个密钥加法层进行密钥漂白时也需要子密钥。
==也就是密钥的扩展比算法的轮数多一个==
如果i不是4的倍数,那么第i列如下:
1 | |
如果i是4的倍数,那么第i列如下:
1 | |
其中T是一个复杂的函数
函数T()首先将4个输入字节进行翻转,并执行一个按字节的S盒代换,最后用第一个字节与轮系数Rcon进行异或运算。轮系数是一个有10个元素的一维数组,一个元素1个字节。T()函数存在的目的有两个,一是增加密钥编排中的非线性;二是消除AES中的对称性(防止不同轮的产生的轮密钥的对称性或者相似性)。这两种属性都是抵抗某些分组密码攻击必要的。
1 | |
密钥加法层
在密钥加法层中有两个输入的参数,分别是明文和子密钥k[0],而且这两个输入都是128位的。
1 | |
字节代换层(S盒)
就是把字节一个个放入s盒之中
1 | |
行移位
1 | |
列混淆
1 | |
接下来我们就只用处理伽罗瓦域乘法相关处理了,由于前面介绍过相关概念,所以代码就不在此进行讲解了,大家可以参考下方的代码注释进行理解:
1 | |




