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

概述

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

1. 密钥扩展

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

/**
* @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轮加密 (字节替换、行移位变换、列混合变换、轮密钥加变换)

代码如下:
/**
* @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. 解密过程

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

/**
* @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 加密算法源码解析所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

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

评论列表共有 0 条评论

立即
投稿
返回
顶部