我是靠谱客的博主 积极篮球,这篇文章主要介绍安全算法-AES 加密算法源码解析,现在分享给大家,希望可以做个参考。

源码是基于 FIPS PUB 197 标准开发的。关于FIPS PUB 197 标准详见《Federal InformationProcessing Standards Publication 197》文件,公众号后台回复 “AES加密 ”可获取。

1. 密钥扩展

如上文3.4章节介绍密钥扩展过程的代码如下:

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
/** * @brief Key Expansion * @param *key 密钥 * @param *w 密钥编排结果 * @retval */ void aes_key_expansion(uint8_t *key, uint8_t *w) { uint8_t tmp[4]; uint8_t i; uint8_t len = Nb*(Nr+1); //分组大小*(轮数+1) //1)将初始密钥以列为主,转化为4个32 bits的字,分别记为w[0…3] for (i = 0; i < Nk; i++) { w[4*i+0] = key[4*i+0]; w[4*i+1] = key[4*i+1]; w[4*i+2] = key[4*i+2]; w[4*i+3] = key[4*i+3]; } //2)依次求解w[i],其中j是整数并且属于[4,43];for (i = Nk; i < len; i++) { tmp[0] = w[4*(i-1)+0]; tmp[1] = w[4*(i-1)+1]; tmp[2] = w[4*(i-1)+2]; tmp[3] = w[4*(i-1)+3]; //3)若i%4=0,则w[i]=w[i-4]⊕g(w[i-1]),否则w[i]=w[i-4]⊕w[i-1];if (i%Nk == 0) { rot_word(tmp); //4)将w循环左移一个字节;sub_word(tmp); //5)分别对每个字节按S盒进行映射;coef_add(tmp, Rcon(i/Nk), tmp); //6)与32 bits的常量(RC[j/4],0,0,0)进行异或 } else if (Nk > 6 && i%Nk == 4) { sub_word(tmp); } w[4*i+0] = w[4*(i-Nk)+0]^tmp[0]; w[4*i+1] = w[4*(i-Nk)+1]^tmp[1]; w[4*i+2] = w[4*(i-Nk)+2]^tmp[2]; w[4*i+3] = w[4*(i-Nk)+3]^tmp[3]; } }

2. 加密过程

1)先得到到扩展密钥 W
2) 把128bit字符放进状态矩阵
3)对状态矩阵进行混淆 S = AddRoundKey(S, W0),
4)在执行Nr轮加密 (字节替换、行移位变换、列混合变换、轮密钥加变换)

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
代码如下: /** * @brief Performs the AES cipher operation * @param *in 明文 * @param *out 加密后的密文 * @param *w 扩展后的密钥 * @retval */ void aes_cipher(uint8_t *in, uint8_t *out, uint8_t *w) { uint8_t state[4*Nb]; uint8_t r, i, j; //STEP2: 把128bit字符放进状态矩阵 for (i = 0; i < 4; i++) { for (j = 0; j < Nb; j++) { state[Nb*i+j] = in[i+4*j]; } } //STEP3: 对状态矩阵进行混淆 add_round_key(state, w, 0); //STEP4: 在执行完Nr轮加密 for (r = 1; r < Nr; r++) { sub_bytes(state); //字节替换 shift_rows(state); //行移位变换 mix_columns(state); //列混合变换 add_round_key(state, w, r); //轮密钥加变换 } sub_bytes(state); shift_rows(state); add_round_key(state, w, Nr); for (i = 0; i < 4; i++) { for (j = 0; j < Nb; j++) { out[i+4*j] = state[Nb*i+j]; } } }

3. 解密过程

解密函数中调用的是各轮操作的逆函数。代码如下:

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
/** * @brief Performs the AES inverse cipher operation * @param *in 密文 * @param *out 密文的逆 * @param *w 扩展后的密钥 * @retval */ void aes_inv_cipher(uint8_t *in, uint8_t *out, uint8_t *w) { uint8_t state[4*Nb]; uint8_t r, i, j; for (i = 0; i < 4; i++) { for (j = 0; j < Nb; j++) { state[Nb*i+j] = in[i+4*j]; } } add_round_key(state, w, Nr); for (r = Nr-1; r >= 1; r--) { inv_shift_rows(state); inv_sub_bytes(state); add_round_key(state, w, r); inv_mix_columns(state); } inv_shift_rows(state); inv_sub_bytes(state); add_round_key(state, w, 0); for (i = 0; i < 4; i++) { for (j = 0; j < Nb; j++) { out[i+4*j] = state[Nb*i+j]; } } }

4. API介绍

  • AddRoundKey()

加密和解密中使用的变换,将一个轮密钥异或到状态上。轮密钥的长度等于状态的大小(即对于 Nb=4, 轮密钥长度等于128bits/16bytes)

  • MixColumns()

加密中使用的变换,以状态的每一列作为输入,混合每一列的数据(彼此独立的)得到新的列。

  • Rcon[]

密钥扩展算法中用到的轮常数

  • RotWord()

密钥扩展算法中使用的函数,对 4-byte 字进行循环移位

  • ShiftRows()

加密中使用的变换, 将状态的最后 3 行循环移动不同的位移量

  • SubBytes()

加密中使用的变换,利用一个非线性字节替代表(S 盒),独立地对状态的每个字节进行操作

  • SubWord()

密钥扩展算法中使用的函数,它以 4-byte 字作为输入,对于 4 字节中的每一字节分别应用 S 盒,得到一个输出字

  • AddRoundKey()

加密和解密中使用的变换,将一个轮密钥异或到状态上。轮密钥的长度等于状态的大小(即对于 Nb=4, 轮密钥长度等于128bits/16bytes)

  • InvMixColumns()

解密中使用的变换, MixColumns()的逆变换

  • InvShiftRows()

解密中使用的变换, ShiftRows()的逆变换

  • InvSubBytes()

解密中使用的变换, SubBytes()的逆变换

更多详细介绍详见代码目录下我用Doxygen软件制作的 index.html 文件

基于 Cortex-M3 完整的程序代码 公众号后台回复 “ AES加密 ” 获取。


阅读原文

最后

以上就是积极篮球最近收集整理的关于安全算法-AES 加密算法源码解析的全部内容,更多相关安全算法-AES内容请搜索靠谱客的其他文章。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(71)

评论列表共有 0 条评论

立即
投稿
返回
顶部