专家
公告
财富商城
电子网
旗下网站
首页
问题库
专栏
标签库
话题
专家
NEW
门户
发布
提问题
发文章
STM32
AES加密解密源码及算法详解资料。
2019-12-09 20:03
发布
×
打开微信“扫一扫”,打开网页后点击屏幕右上角分享按钮
站内问答
/
STM32/STM8
7795
71
72
一份非常不错的AES加密解密原理及算法学习的资料。所附源码经本人实测,完全无误。并且可移植性强,可移植到任意平台运行,从而为系统添加AES加密解密的功能。
友情提示:
此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
71条回答
BS_good200xy
1楼-- · 2019-12-14 15:48
AES(Rijndael算法)
Rijndael算法首先是一个密钥分组加密的算法,通过置换(permutations )和替换(substitutions)迭代加密,进过多轮操作形成密文。AES算是Rijndael算法的一种特殊实现,选的分组为128bit(16字节),密钥可以使用128、192 和 256bit三种。
分组
上面已经说了AES分组为16个字节,下面说说他的排列,其实就是一个4x4的矩阵,不过要注意是竖着排的。
AES原文:a1a2a3a4 a5a6a7a8 a9a10a11a12 a13a14a15a16...
a1 a5 a9 a13
a2 a6 a10 a14
a3 a7 a11 a15
a4 a8 a12 a16
密钥
AES的密钥虽然有三种,但是并不意味着这三种密钥的AES差异很大,相反加密过程其实完全一样,只是种子密钥是128,192,256bit三种而已。密钥在AES与分组数据并没有做非常复杂的变化,其实只是简单的&(与)操作而已。不过又因为AES算法有很多轮,所有单单的种子密钥是不够的,所有AES有自己的扩展密钥的方法。还要提一下,密钥扩展后也是竖着排成方阵的。
key:k1k2k3k4 k5k6k7k8 k9k10k11k12 k13k14k15k16...
k1 k5 k9 k13
k2 k6 k10 k14
k3 k7 k11 k15
k4 k8 k12 k16
轮数
轮数主要跟种子密钥长度有关。
一般习惯用Nk表示密钥所含的数据字数,一字表示32bit,也就是4字节,也就是一竖排。
128,192,256bit对应Nk=4,6,8
一般习惯用Nr表示轮数
Nr = Nk+6也就是10,12,14
密钥扩展(KeyExpansion)
对与密钥扩展其实只要关心两点:一是扩展成多长,这个其实跟加密过程有关,暂时只要知道密钥总长度为(分组大小=16个字节)*(Nr+1),也就是4*(Nr+1)字,下面讲过程的时候就会明白为什么要这么长。二是密钥扩展的算法,密钥的算法其实比较复杂,但是却不难理解。
注:Nk密钥字数,字为4字节也就是一竖排。
算法步骤如下:
Nk ≤ 6 的密钥扩展
1)最前面的 Nk 个字是由种子密钥填充的。
2)之后的每一个字 W[j] 等于前面的字 W[j-1] 的与 Nk 个位置之前的字 W[j-Nk]的异或。
3)而且对于 Nk 的整数倍的位置处的字,在异或之前,对 W[j-1] 的进行如下变换:
.字节的循环移位 RotByte->即当输入字为 (a,b,c,d) 时,输出字为 (b , c, d, a )
.用 S 盒进行变换次位元组
.异或轮常数 Rcon[i/Nk]
伪代码
KeyExpansion (byteKey[4*Nk] , W[Nb*(Nr+1)])
{
for (i =0; i < Nk; i ++)
W[i]=(Key[4* i],Key[4* i +1],Key[4* i +2],Key[4* i +3] );
//扩展密钥的前面4个字由种子密钥组成
for (i =Nk; i <Nb*(Nr+1); i ++)
{
temp=W[i-1];
if (i % Nk= =0)
temp=SubByte (RotByte (temp))^Rcon[i /Nk];
//i是NK的整数倍是要特殊处理
W[i]=W[i-Nk]^ temp;
}
}
Nk > 6 的密钥扩展
KeyExpansion (byte Key[4*Nk] , W[Nb*(Nr+1)])
{
for (i=0; i < Nk; i ++)
W[i]=(Key[4* i], Key[4* i +1], Key[4* i +2], Key[4* i +3] );
//扩展密钥的前面4个字由种子密钥组成
for (i =Nk; i <Nb*(Nr+1); i ++)
{
temp=W[i -1];
if (i % Nk= =0)
temp=SubByte (RotByte (temp))^Rcon[i /Nk];
//i是NK的整数倍是要特殊处理
else if (i % Nk==4)
temp=SubByte (temp);
//i是4的整数倍是要特殊处理
W[i]=W[i - Nk]^ temp;
}
}
异或轮常数 Rcon[i/Nk] :Rcon[i/Nk]=(RC[i/Nk]],’00’,’00’,’00’)(i一定会大于Nk)
RC[1]=‘01’
RC[x]=2⊙RC[x-1]
(其实我也不懂Rcon,不过有人已经算好了如下
RC[1]=(01, 00, 00, 00),
RC[2]=(02, 00, 00, 00),
RC[3]=(04, 00, 00, 00),
RC[4]=(08, 00, 00, 00),
RC[5]=(10, 00, 00, 00),
RC[6]=(20, 00, 00, 00),
RC[7]=(40, 00, 00, 00),
RC[8]=(80, 00, 00, 00),
RC[9]=(1b, 00, 00, 00),
RC[10]=(36, 00, 00, 00))
加载中...
TANG2016
2楼-- · 2019-12-14 16:27
上次弄了一个例程运行一段时间会死机,可能是没有释放内存。
加载中...
kap
3楼-- · 2019-12-14 18:26
精彩回答 2 元偷偷看……
加载中...
十三少
4楼-- · 2019-12-14 20:32
楼主无私精神,值得学习!
加载中...
BS_good200xy
5楼-- · 2019-12-14 22:30
希望能多多交流,共同进步!也希望大家能把在AES学习及应用方面碰到的问题及收获在此分享。
加载中...
canspider
6楼-- · 2019-12-15 03:59
如果是单片机里面用的话
1. 16字符变数组没必要
2. sbox,rcon节约rom可以动态生成,比如空间紧张的bootloader
3. 那几个GFMul其实有关联,可以优化
加载中...
首页
上一页
5
6
7
8
9
10
11
12
下一页
一周热门
更多
>
相关问题
STM32F4上I2C(在PROTEUS中模拟)调试不通的问题
6 个回答
芯片供应紧张,准备换个MCU,MM32L系列替换STM32L系列的怎么样?
7 个回答
STM32同时使用两个串口进行数据收发时数据丢包的问题
5 个回答
STM32F103串口通信死机问题
4 个回答
STM32WLE5CC连接SX1268在LoRa模式下能与 SX1278互通吗?
2 个回答
STM32开发板免费用活动
7 个回答
stm32 处理 DHT11占用太多时间,大家程序是怎么设计的
8 个回答
分享一个STM32单片机做的离线编程器代码
9 个回答
相关文章
ST公司第一款无线低功耗单片机模块有效提高物联网设计生产效率
0个评论
如何实现对单片机寄存器的访问
0个评论
通过USB用STM32片内自带Bootloader下载程序及注意事项
0个评论
欲练此功必先自宫之STM32汇编启动,放慢是为了更好的前行
0个评论
×
关闭
采纳回答
向帮助了您的网友说句感谢的话吧!
非常感谢!
确 认
×
关闭
编辑标签
最多设置5个标签!
STM32
保存
关闭
×
关闭
举报内容
检举类型
检举内容
检举用户
检举原因
广告推广
恶意灌水
回答内容与提问无关
抄袭答案
其他
检举说明(必填)
提交
关闭
×
关闭
您已邀请
15
人回答
查看邀请
擅长该话题的人
回答过该话题的人
我关注的人
Rijndael算法首先是一个密钥分组加密的算法,通过置换(permutations )和替换(substitutions)迭代加密,进过多轮操作形成密文。AES算是Rijndael算法的一种特殊实现,选的分组为128bit(16字节),密钥可以使用128、192 和 256bit三种。
分组
上面已经说了AES分组为16个字节,下面说说他的排列,其实就是一个4x4的矩阵,不过要注意是竖着排的。
AES原文:a1a2a3a4 a5a6a7a8 a9a10a11a12 a13a14a15a16...
a1 a5 a9 a13
a2 a6 a10 a14
a3 a7 a11 a15
a4 a8 a12 a16
密钥
AES的密钥虽然有三种,但是并不意味着这三种密钥的AES差异很大,相反加密过程其实完全一样,只是种子密钥是128,192,256bit三种而已。密钥在AES与分组数据并没有做非常复杂的变化,其实只是简单的&(与)操作而已。不过又因为AES算法有很多轮,所有单单的种子密钥是不够的,所有AES有自己的扩展密钥的方法。还要提一下,密钥扩展后也是竖着排成方阵的。
key:k1k2k3k4 k5k6k7k8 k9k10k11k12 k13k14k15k16...
k1 k5 k9 k13
k2 k6 k10 k14
k3 k7 k11 k15
k4 k8 k12 k16
轮数
轮数主要跟种子密钥长度有关。
一般习惯用Nk表示密钥所含的数据字数,一字表示32bit,也就是4字节,也就是一竖排。
128,192,256bit对应Nk=4,6,8
一般习惯用Nr表示轮数
Nr = Nk+6也就是10,12,14
密钥扩展(KeyExpansion)
对与密钥扩展其实只要关心两点:一是扩展成多长,这个其实跟加密过程有关,暂时只要知道密钥总长度为(分组大小=16个字节)*(Nr+1),也就是4*(Nr+1)字,下面讲过程的时候就会明白为什么要这么长。二是密钥扩展的算法,密钥的算法其实比较复杂,但是却不难理解。
注:Nk密钥字数,字为4字节也就是一竖排。
算法步骤如下:
Nk ≤ 6 的密钥扩展
1)最前面的 Nk 个字是由种子密钥填充的。
2)之后的每一个字 W[j] 等于前面的字 W[j-1] 的与 Nk 个位置之前的字 W[j-Nk]的异或。
3)而且对于 Nk 的整数倍的位置处的字,在异或之前,对 W[j-1] 的进行如下变换:
.字节的循环移位 RotByte->即当输入字为 (a,b,c,d) 时,输出字为 (b , c, d, a )
.用 S 盒进行变换次位元组
.异或轮常数 Rcon[i/Nk]
伪代码
KeyExpansion (byteKey[4*Nk] , W[Nb*(Nr+1)])
{
for (i =0; i < Nk; i ++)
W[i]=(Key[4* i],Key[4* i +1],Key[4* i +2],Key[4* i +3] );
//扩展密钥的前面4个字由种子密钥组成
for (i =Nk; i <Nb*(Nr+1); i ++)
{
temp=W[i-1];
if (i % Nk= =0)
temp=SubByte (RotByte (temp))^Rcon[i /Nk];
//i是NK的整数倍是要特殊处理
W[i]=W[i-Nk]^ temp;
}
}
Nk > 6 的密钥扩展
KeyExpansion (byte Key[4*Nk] , W[Nb*(Nr+1)])
{
for (i=0; i < Nk; i ++)
W[i]=(Key[4* i], Key[4* i +1], Key[4* i +2], Key[4* i +3] );
//扩展密钥的前面4个字由种子密钥组成
for (i =Nk; i <Nb*(Nr+1); i ++)
{
temp=W[i -1];
if (i % Nk= =0)
temp=SubByte (RotByte (temp))^Rcon[i /Nk];
//i是NK的整数倍是要特殊处理
else if (i % Nk==4)
temp=SubByte (temp);
//i是4的整数倍是要特殊处理
W[i]=W[i - Nk]^ temp;
}
}
异或轮常数 Rcon[i/Nk] :Rcon[i/Nk]=(RC[i/Nk]],’00’,’00’,’00’)(i一定会大于Nk)
RC[1]=‘01’
RC[x]=2⊙RC[x-1]
(其实我也不懂Rcon,不过有人已经算好了如下
RC[1]=(01, 00, 00, 00),
RC[2]=(02, 00, 00, 00),
RC[3]=(04, 00, 00, 00),
RC[4]=(08, 00, 00, 00),
RC[5]=(10, 00, 00, 00),
RC[6]=(20, 00, 00, 00),
RC[7]=(40, 00, 00, 00),
RC[8]=(80, 00, 00, 00),
RC[9]=(1b, 00, 00, 00),
RC[10]=(36, 00, 00, 00))
1. 16字符变数组没必要
2. sbox,rcon节约rom可以动态生成,比如空间紧张的bootloader
3. 那几个GFMul其实有关联,可以优化
一周热门 更多>