AES算法(PS:此为128版本且只有键盘输入无文本输入)纯C语言实现加密解密

何为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);
        }
    }
}

结果

行移位:

  • 3
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值