S-AES加密实现

这篇具有很好参考价值的文章主要介绍了S-AES加密实现。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

S-AES加密实现

S-AES是AES的简化版本,其只使用了16位的明文和16位的密钥进行加密。以下介绍S-AES的加密步骤。

测试数据:使用密钥1010 0111 0011 1011加密二进制明文0110 1111 0110 1011,得出二进制密文0000 0111 0011 1000

总体加密思路

简化版的AES和原本AES的步骤差不多,只是在轮数和一些运算的字节数上有不同。

S-AES加密的整体步骤示意图如下

S-AES加密实现

接下来从扩展密钥到明文加密开始进行步骤阐述。

密钥扩展

由于只需要加密两轮,因此只需要扩展出两个密钥即可,包括原始密钥总共6个字节。扩展密钥步骤的示意图如下

S-AES加密实现

将16位密钥分为左右两部分,每一部分各8位。记原始密钥为第0个密钥。

在计算第i个密钥时,首先将第i-1个密钥的右半部分(8位)进行左循环移位,即将第i-1个密钥的右半部分的左右4位进行交换,再将左循环移位后的第i-1个密钥的右半部分(8位)进行S盒置换,S-AES的S盒定义如下:

S-AES加密实现

进行S盒置换后需要与轮常数进行异或,S-AES的轮常数定义为:第一轮加密的轮常数是【1000 0000】,第二轮加密的轮常数是【0011 0000】。

上述步骤就是示意图中函数g的步骤,将第i-1个密钥的右半部分(8位)执行完上述步骤后得到g(第i-1个密钥的右半部分),将其与第i-1个密钥的左半部分(8位)进行异或得到第i个密钥的左半部分。

i个密钥的右半部分由第i个密钥的左半部分与第i-1个密钥的右半部分进行异或得到。

计算出的两个扩展密钥是:

key1:0001 1100 0010 0111 
key2:0111 0110 0101 0001

明文加密

第0轮加密

只有将明文进行轮密钥加操作,即把明文按位与第0个密钥(原始输入密钥)进行异或。以下统称每一步骤处理完的都为明文。

第1轮加密

半字节代替

使用S盒将明文进行半字节的代替,就是一个简单的查表。具体步骤为:

S-AES加密实现

行位移

将一个字节排列成两行一列,即一行有四位,第二个字节按照这种方式形成第二列。第一行不进行移位,第二行循环左移位,一次移动4位。示例如下:

S-AES加密实现

其中60是一个字节,4C是一个字节。

列混淆

简单来说列混淆就是乘上一个矩阵,运算定义在 G F ( 2 4 ) GF(2^4) GF(24) 上。列混淆矩阵是:

S-AES加密实现

则与明文进行运算示意图为:

S-AES加密实现

其中等式左边的右侧矩阵为明文, S 0 , 0 S_{0,0} S0,0 S 1 , 0 S_{1,0} S1,0 是一个字节,各为4位。 S 0 , 1 S_{0,1} S0,1 S 1 , 1 S_{1,1} S1,1 是一个字节,各为4位。执行乘法后可得到:

S-AES加密实现

示意图右边即为列混淆后的结果。

第2轮加密

进行第二轮加密时,只有半字节代替,行移位和轮密钥加三个步骤,具体过程和第一轮一样,轮密钥加使用的是扩展密钥2即key2文章来源地址https://www.toymoban.com/news/detail-401133.html

经过上述步骤之后的结果就是密文了。

程序实现(C++)

#include <bits/stdc++.h>
using namespace std;

// TODO 实现x^nfx的函数
void x_de_n_fang_cheng_fx(int xfx[4], int a[4]) //* xfx是结果,a是上一步的结果
{
    //! 注意要取模
    //! 既约多项式是 x^4 + x + 1
    //* 保存四次乘法的系数
    if (a[0] == 0)
    {
        for (int i = 0; i < 3; i++)
            xfx[i] = a[i + 1];
    }
    else
    {
        //! 如果乘数首项不为1就需要将 b1x^2+b0x 与 x+1 进行异或
        xfx[1] = a[2];
        xfx[2] = a[3] == 1 ? 0 : 1;
        xfx[3] = 1;
    }
}
// TODO 乘法
int *chengfa(int a[4], int b[4])
{
    //* 储存结果的系数
    int *result = new int[4];
    for (int i = 0; i < 4; i++)
        result[i] = 0;

    //* 记录下x^nfx
    int xfx[4] = {0};
    x_de_n_fang_cheng_fx(xfx, a);
    int x2fx[4] = {0};
    x_de_n_fang_cheng_fx(x2fx, xfx);
    int x3fx[4] = {0};
    x_de_n_fang_cheng_fx(x3fx, x2fx);

    //* 现在需要根据多项式a和b开始异或
    if (b[0] == 1)
        for (int i = 0; i < 4; i++)
            result[i] ^= x3fx[i];
    if (b[1] == 1)
        for (int i = 0; i < 4; i++)
            result[i] ^= x2fx[i];
    if (b[2] == 1)
        for (int i = 0; i < 4; i++)
            result[i] ^= xfx[i];
    if (b[3] == 1)
        for (int i = 0; i < 4; i++)
            result[i] ^= a[i];
    return result;
}

const int s[4][4] = {
    {9, 4, 10, 11},
    {13, 1, 8, 5},
    {6, 2, 0, 3},
    {12, 14, 15, 7}};

const int tihuanwei[16][4] = {
    {0, 0, 0, 0},
    {0, 0, 0, 1},
    {0, 0, 1, 0},
    {0, 0, 1, 1},
    {0, 1, 0, 0},
    {0, 1, 0, 1},
    {0, 1, 1, 0},
    {0, 1, 1, 1},
    {1, 0, 0, 0},
    {1, 0, 0, 1},
    {1, 0, 1, 0},
    {1, 0, 1, 1},
    {1, 1, 0, 0},
    {1, 1, 0, 1},
    {1, 1, 1, 0},
    {1, 1, 1, 1}};
// const int tihuanwei[4][4][4] = {
//     {{1, 0, 0, 1},{0, 1, 0, 0},{1, 0, 1, 0},{1, 0, 1, 1}},
//     {{1, 1, 0, 1},{0, 0, 0, 1},{1,0,0,0},{0,1,0,1}},
//     {{0,1,1,0},{0,0,1,0},{0,0,0,0},{0,0,1,1}},
//     {{1,1,0,0},{1,1,1,0},{1,1,1,1},{0,1,1,1}}};


//* 定义轮常数
int rcon1[8] = {1, 0, 0, 0, 0, 0, 0, 0};
int rcon2[8] = {0, 0, 1, 1, 0, 0, 0, 0};

int *yihuo8(int *a, int *b)//8位的异或
{
    int *t = new int[8];
    for (int i = 0; i < 8; i++)
        t[i] = a[i] ^ b[i];
    return t;
}

int *yihuo4(int *a, int *b)//4位的异或
{
    int *t = new int[4];
    for (int i = 0; i < 4; i++)
        t[i] = a[i] ^ b[i];
    return t;
}

void s_he_tihuan(int *temp) //使用s盒替换的函数,8位换
{
    int t1 = 2 * temp[0] + temp[1];
    int t2 = 2 * temp[2] + temp[3];
    int t3 = 2 * temp[4] + temp[5];
    int t4 = 2 * temp[6] + temp[7];
    int tihuan1 = s[t1][t2]; //记录替换后的数字
    int tihuan2 = s[t3][t4];
    //* 四位四位进行替换
    for (int i = 0; i < 4; i++)
        temp[i] = tihuanwei[tihuan1][i];
    for (int i = 0; i < 4; i++)
        temp[i + 4] = tihuanwei[tihuan2][i];
}

void zuoyi(int **temp) //循环左移
{
    //! 掉大坑!!!!注意半字节排列的方式,这里应该是第一字节的右半部分和第二字节的右半部分进行替换
    for(int i = 4;i < 8;i ++)
    {
        int t = temp[0][i];
        temp[0][i] = temp[1][i];
        temp[1][i] = t;
    }
}
int *g(int *temp, int *rcon) // temp是一个八位的数组,rcon是轮常数
{
    //! 注意这个temp是密钥,不能改动,要复制一个新的进行计算
    int *t = new int[8];
    for (int i = 0; i < 8; i++)
        t[i] = temp[i];
    //* 循环左移
    for (int i = 0; i < 4; i++)
    {
        int tt = t[i + 4];
        t[i + 4] = t[i];
        t[i] = tt;
    }

    //* 进行s盒替换
    s_he_tihuan(t);

    //* 进行轮常数异或
    return yihuo8(t, rcon);
}

void liehunxiao(int **mingwen)
{
    int si_de2jinzhi[4] = {0, 1, 0, 0};
    int *m00 = new int[4];
    int *m10 = new int[4];
    int *m01 = new int[4];
    int *m11 = new int[4];
    for (int i = 0; i < 4; i++)
    {
        m00[i] = mingwen[0][i];
        m10[i] = mingwen[0][i + 4];
        m01[i] = mingwen[1][i];
        m11[i] = mingwen[1][i + 4];
    }
    int *n00 = new int[4];
    int *n10 = new int[4];
    int *n01 = new int[4];
    int *n11 = new int[4];
    n00 = yihuo4(m00, chengfa(si_de2jinzhi, m10));//乘法结果是1011
    n10 = yihuo4(chengfa(si_de2jinzhi, m00), m10);//0101
    n01 = yihuo4(m01, chengfa(si_de2jinzhi, m11));//0100
    n11 = yihuo4(chengfa(si_de2jinzhi, m01), m11);//0010
    for (int i = 0; i < 4; i++)
    {
        mingwen[0][i] = n00[i];
        mingwen[0][i + 4] = n10[i];
        mingwen[1][i] = n01[i];
        mingwen[1][i + 4] = n11[i];
    }
}

void lunmiyaojia(int **mingwen, int **key)
{
    for (int i = 0; i < 2; i++)
        for (int j = 0; j < 8; j++)
            mingwen[i][j] ^= key[i][j];
}

//用于输出
void shuchu(int **a)
{
    for (int i = 0; i < 2; i++)
        for (int j = 0; j < 8; j++)
            cout << a[i][j] << ' ';
    cout << endl;
}

int main()
{
    //* 输入明文和密钥
    int **mingwen = new int *[2];
    for (int i = 0; i < 2; i++)
        mingwen[i] = new int[8];
    int **key = new int *[2];
    for (int i = 0; i < 2; i++)
        key[i] = new int[8];
    for (int i = 0; i < 2; i++)
        for (int j = 0; j < 8; j++)
            cin >> mingwen[i][j];
    for (int i = 0; i < 2; i++)
        for (int j = 0; j < 8; j++)
            cin >> key[i][j];

    //* 密钥扩展算法,由于只有三轮加密,第一轮还只使用了原始key
    int **key1 = new int *[2];
    for (int i = 0; i < 2; i++)
        key1[i] = new int[8];
    int **key2 = new int *[2];
    for (int i = 0; i < 2; i++)
        key2[i] = new int[8];

    key1[0] = yihuo8(key[0], g(key[1], rcon1));
    key1[1] = yihuo8(key1[0], key[1]);
    key2[0] = yihuo8(key1[0], g(key1[1], rcon2));
    key2[1] = yihuo8(key2[0], key1[1]);

    //* 第0轮的轮密钥加
    lunmiyaojia(mingwen, key);

    //*第一轮
    //* 明文半字节代替
    s_he_tihuan(mingwen[0]);
    s_he_tihuan(mingwen[1]);
    //* 明文的行移位
    zuoyi(mingwen);
    //* 明文的列混淆
    liehunxiao(mingwen);
    //* 明文的轮密钥加
    lunmiyaojia(mingwen, key1);

    //*第二轮
    //* 明文半字节代替
    s_he_tihuan(mingwen[0]);
    s_he_tihuan(mingwen[1]);
    
    //* 明文的行移位
    zuoyi(mingwen);
    //* 明文的轮密钥加
    lunmiyaojia(mingwen, key2);

    //* 现在的明文其实是密文了
    shuchu(mingwen);
    return 0;
}
/*
0 1 1 0 1 1 1 1 0 1 1 0 1 0 1 1
1 0 1 0 0 1 1 1 0 0 1 1 1 0 1 1
*/

到了这里,关于S-AES加密实现的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • RSA+AES实现混合加密

    为什么使用RSA + AES混合加密 1.加密介绍 RSA加密: 属于非对称加密,公钥用于对数据进行加密,私钥对数据进行解密,两者不可逆。公钥和私钥是同时生成的,且一一对应。比如:客户端拥有公钥,服务端拥有公钥和私钥。客户端将数据通过公钥进行加密后,发送密文给服务端

    2024年02月05日
    浏览(37)
  • AES加密解密python实现

            关于现代密码学算法,可以查看以下博客全面了解 CISSP考试要求里的“应用密码学”内容辅助记忆趣味串讲_晓翔仔的博客-CSDN博客         AES的细节知识,可以查阅 AES加密算法的详细介绍与实现_TimeShatter的博客-CSDN博客          AES 加密最常用的模式就是

    2024年02月05日
    浏览(64)
  • C# 实现对称加密算法(AES)与非对称加密算法(RSA),包含前端加密对应算法实现

    一种既简单速度又快的加密方式,加密与解密使用的都是同一个密钥,别名又叫做:单密钥加密;对称加密有很多公开算法,并且因为它效率很高,所以适用于加密大量数据的场合;但其密钥的传输过程是不安全的,并且容易被破解,密钥管理起来也相对麻烦。 需要两个密钥

    2024年02月09日
    浏览(48)
  • Java 实现 AES 加密和解密完整示例

    AES,全称为 Advanced Encryption Standard,是一种分组密码算法,用于保护敏感数据的传输和存储。AES 分为 128 位和 256 位两种密钥长度,可以对数据进行加密和解密,保证数据的安全性和完整性。AES 主要应用于电子商务、移动支付、网络安全等领域,被广泛运用于现代社会的各个

    2024年02月04日
    浏览(50)
  • PYTHON实现AES加密,中英文通用!!!

    AES是一种对称加密,所谓对称加密就是加密与解密使用的秘钥是一个。在日常的开发中,无论是实现前后端的接口数据加密,还是数据传输安全性,都使用了AES加密,本文章将从python的角度去实现AES的加密和解密 AES的加密方式有很多种,例如ECB、CBC、CTR、OFB、CFB,最常用的是

    2024年02月12日
    浏览(32)
  • Java实现AES加密工具类 - 简单易用的数据加密解决方案

    当我们涉及到敏感数据的存储和传输时,数据加密是非常重要的。加密可以确保数据的保密性和完整性,并帮助我们防止数据泄露和攻击。在Java中,使用标准的加密算法和库可以很容易地实现数据加密和解密。本篇文章将介绍一个简单的Java工具类,该工具类使用AES对称加密

    2024年02月11日
    浏览(34)
  • AES白盒加密解读与实现(Chow方案)

    近日开始学白盒密码,没有技巧,全靠头发,特此记录. 在AES加密中通常分以下四个模块: 设中间值变量为state,它通常被描述为一个二维的字节数组,即,一个4×4数组。 轮密钥加(AddRoundKey) :中间值state与16字节轮密钥进行异或。 字节替换(SubBytes) :通过S盒完成一个字

    2024年02月13日
    浏览(25)
  • java | 使用Cipher类实现AES所有常用加密模式

    AES 密码学中的高级加密标准(Advanced Encryption Standard,AES),又称Rijndael加密法,是美国联邦政府采用的一种区块加密标准。这个标准用来替代原先的DES(Data Encryption Standard),已经被多方分析且广为全世界所使用。 AES 是对称加密算法,优点:加密速度快;缺点:如果秘钥丢

    2024年02月13日
    浏览(26)
  • 实现 MyBatis-Plus 中的配置加密功能(使用 AES 算法)

    在项目开发过程中,为了增强数据安全性,我们常常需要对敏感信息进行加密处理。MyBatis-Plus 提供了方便的配置加密功能,使我们能够对配置文件中的敏感信息进行加密和解密操作。本文将详细介绍如何实现 MyBatis-Plus 中的配置加密功能,并给出相应的代码示例。 首先,我们

    2024年02月07日
    浏览(28)
  • iOS MT19937随机数生成,结合AES-CBC加密算法实现。

    按处理顺序说明: 1. 生成随机数序列字符串函数 生成方法MT19937,初始种子seed,利用C++库方法,生成: 2. 对第一部中的随机数序列字符串进行sha256加密,得到64字节的一个数据流函数。  3. AES-CBC加密解密方法 /*     CCCrypt方法提供了CBC 和 ECB 两种AES加密模式,     如果不传

    2024年04月09日
    浏览(40)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包