网上实现AES的例子很多,但是错误的和遗漏的也很多,大概是一知半解的人和转载的人很多导致的,所以我打算自己撸一遍算法,以保证后续使用的时候既能保证正确又能开箱即用,也仅供其他人参考。
1. 算法流程
算法流程中,在之前的笔记中讲到的部分是:
- AES加密算法-密钥扩展;扩展密钥,加密过程给的原始密码不能用来直接去加密,要进行一系列步骤扩展成每一轮都是用的密钥,这个密钥不仅要求非线性(S盒替换),还要求密钥有一定的扩散(你可以是试着设置密码给1111,2222这样的密码来分析加密过程的对应关系)。
- AES加密算法-S盒构造;字节替换,非线形替换就是用S盒的值替换原来的值,这是加密部分唯一的非线形处理部分,这样明文和密文之间不会有一一对应的关系.
先贴具体的流程图,如下图参考:
2. 单个步骤细节
行移位和列混淆以及轮密钥相加;皆是为了保证非线形处理后的密文不能存在一种数学上的线形特征。
2.1 循环行移位

之前在密钥扩展的时候讲过循环左移位,不过那是四个字节的左移,这里是4x4的左移动,代码实现如下:
1 | void shift_rows(uint8_t *state) { |
2.2 列混淆

1 | // 列混淆 |
2.3 轮密钥相加
1 | // 这里是简单的4x4矩阵相加(XOR) |
2.4 字节替换(S盒替换)
之前密钥扩展时用到了字节替换(S盒替换),但那是一个4字节的替换,这里是4x4矩阵里逐个替换.
1 | void sub_bytes(uint8_t *state) { |
3. 算法整体实现
3.1 加密流程
参考第一节流程图的代码实现如下:
1 | void cipher(uint8_t *in, uint8_t *out, uint8_t *w) { |
3.2 实例:
1 | int main() { |
附录:
4x4矩阵乘法,两个4x4的矩阵乘法,就是值等于各项乘积之和.
1 | void coef_mult(uint8_t *a, uint8_t *b, uint8_t *d) { |
v1.4.14