何为AES?
这里我只给出AES加密算法的流程(解密的大致与加密相同,只是过程不一样而已),剩余的还需要各位大佬自己学习。
本文以
明文:ILoveYouYouKnow?
密钥:1111111111111111
为样例进行解说,里面会有每一步的结果。
首先给个流程图:
可以看到明文首先会跟第一个子密钥矩阵进行轮密钥加,所以我们的第一步是产生子密钥,但是产生多少子密钥呢??这里是AES-128共有10轮循环,所以我们也要有10轮的子密钥,而且每轮的子密钥为4*4的矩阵,所以我们一共需要产生44个密钥对。
如何产生呢??
首先有个Rcon常数表:
这个表是干啥的?
密钥W[i]在过程中,这一轮的密钥.如果i不是4的倍数,那么第i列由如下等式确定:
W[i]=W[i-4]⨁W[i-1]
2.如果i是4的倍数,那么第i列由如下等式确定:
W[i]=W[i-4]⨁T(W[i-1])
其他的都去百度吧,这里不给出解释。
就这样我们得到了44列密钥即10轮子密钥,
在本文中44列密钥是这样的的:
然后得到10轮子密钥矩阵
这里面我是用没有任何技巧的C语言直接打出来的代码有点繁琐,大佬看看就好:
代码实现:
///密钥扩展
void tuozhan()
{
for(int i=0; i<4; i++)
{
for(int j=0; j<4; j++)
{
strcpy(K[i][j],miyaojuzhen[j][i]);
}
}
for(int i=4; i<44; i++)
{
for(int j=0; j<4; j++)
{
int n1=0,n2=0;
if(strlen(K[i-4][j])==2)///K[I-4]为必求
{
if(K[i-4][j][0]>='A'&&K[i-4][j][0]<='F')
n1+=((K[i-4][j][0]-55)*16);
else if(K[i-4][j][0]>='a'&&K[i-4][j][0]<='f')
n1+=((K[i-4][j][0]-'a'+10)*16);
else
n1+=(K[i-4][j][0]-'0')*16;
if(K[i-4][j][1]>='A'&&K[i-4][j][1]<='F')
n1+=((K[i-4][j][1]-55));
else if(K[i-4][j][1]>='a'&&K[i-4][j][1]<='f')
n1+=((K[i-4][j][1]-'a'+10));
else
n1+=((K[i-4][j][1]-'0'));
}
else
{
if(K[i-4][j][0]>='A'&&K[i-4][j][0]<='F')
n1+=((K[i-4][j][0]-55));
else if(K[i-4][j][0]>='a'&&K[i-4][j][0]<='f')
n1+=((K[i-4][j][0]-'a'+10));
else
n1+=(K[i-4][j][0]-'0');
}
if(i%4==0)///如果为4的倍数则;Ki=Ki-4^T(Ki-1)
{
///获取T(Ki-1)
int h=0,l=0;
if(strlen(K[i-1][(j+1)%4])==1)
{
h=0;
if(K[i-1][(j+1)%4][0]>='A'&&K[i-1][(j+1)%4][0]<='F')
l=K[i-1][(j+1)%4][0]-'A'+10;
else if(K[i-1][(j+1)%4][0]>='a'&&K[i-1][(j+1)%4][0]<='f')
l=K[i-1][(j+1)%4][0]-'a'+10;
else
l=K[i-1][(j+1)%4][0]-'0';
}
else
{
if(K[i-1][(j+1)%4][0]>='A'&&K[i-1][(j+1)%4][0]<='F')
h=K[i-1][(j+1)%4][0]-'A'+10;
else if(K[i-1][(j+1)%4][0]>='a'&&K[i-1][(j+1)%4][0]<='f')
h=K[i-1][(j+1)%4][0]-'a'+10;
else
h=K[i-1][(j+1)%4][0]-'0';
if(K[i-1][(j+1)%4][1]>='A'&&K[i-1][(j+1)%4][1]<='F')
l=K[i-1][(j+1)%4][1]-'A'+10;
else if(K[i-1][(j+1)%4][1]>='a'&&K[i-1][(j+1)%4][1]<='f')
l=K[i-1][(j+1)%4][1]-'a'+10;
else
l=K[i-1][(j+1)%4][1]-'0';
}
if(h>16)
h-=7;
if(l>16)
l-=7;
int temps=s[h][l];///得到s盒中的输出
///正确
int rcon=Rcon[i/4-1];///不能直接得到
if(j==0)
n2=temps^rcon;///异或得到每一个输入
else
n2=temps;
///得到的T函数与K[i-4]异或
}
else ///Ki=Ki-4^Ki-1
{
if(strlen(K[i-1][j])==2)
{
if(K[i-1][j][0]>='A'&&K[i-1][j][0]<='F')
n2+=((K[i-1][j][0]-55)*16);
else
n2+=(K[i-1][j][0]-'0')*16;
if(K[i-1][j][1]>='A'&&K[i-1][j][1]<='F')
n2+=((K[i-1][j][1]-55));
else
n2+=((K[i-1][j][1]-'0'));
}
else
{
if(K[i-1][j][0]>='A'&&K[i-1][j][0]<='F')
n2+=((K[i-1][j][0]-55));
else
n2+=(K[i-1][j][0]-'0');
}
}
int n3=n1^n2;///异或产生
char temp[10];
sprintf(temp,"%X",n3);
strcpy(K[i][j],temp);
}
}
}
void keychoice()///得到轮密钥验证正确
{
tuozhan();///验证正确,得到44个扩展密钥
int l=0;
for(int i=0; i<44; i++)
{
if(i%4==0&&i!=0)
l++;
for(int j=0; j<4; j++)
{
strcpy(key[l][j][(i)%4],K[i][j]);
}
}
}
到这里我们的10轮子密钥就产生完了,然后我们在对第0轮的子密钥与明文矩阵轮密钥相加即异或一下得到下一次的输入
轮密钥加得到结果
:
再然后就进入了循环操作——字节代换,行移位,列混合,轮密钥加。
由于这里面都是循环操作,所以我们只需要明白一轮就好,至于如何实现,请自行学习
代码实现如下
字节代换:
///字节代换
void bitchange()///验证正确
{
for(int i=0; i<4; i++)
{
for(int j=0; j<4; j++)
{
int h=0,l=0;
if(strlen(mingjuzhen[i][j])==1)
{
h=0;
l=mingjuzhen[i][j][0]-'0';
}
else
{
h=mingjuzhen[i][j][0]-'0';
l=mingjuzhen[i][j][1]-'0';
}
if(h>16)
h-=7;
if(l>16)
l-=7;
int temp=s[h][l];
char ss[10];
sprintf(ss,"%X",temp);
strcpy(mingjuzhen[i][j],ss);
}
}
}
结果
: