zoukankan      html  css  js  c++  java
  • Aes加密算法加密模式介绍

    本文转自:https://www.jianshu.com/p/582d3a47729a

       AES,高级加密标准(英语:Advanced Encryption Standard,缩写:AES),在密码学中又称Rijndael加密法,是美国联邦政府采用的一种区块加密标准。这个标准用来替代原先的DES,已经被多方分析且广为全世界所使用。严格地说,AES和Rijndael加密法并不完全一样(虽然在实际应用中二者可以互换),因为Rijndael加密法可以支持更大范围的区块和密钥长度:AES的区块长度固定为128 比特,密钥长度则可以是128,192或256比特;而Rijndael使用的密钥和区块长度可以是32位的整数倍,以128位为下限,256比特为上限。包括AES-ECB,AES-CBC,AES-CTR,AES-OFB,AES-CFB

    简介

      一般的加密通常都是块加密,如果要加密超过块大小的数据,就需要涉及填充和链加密模式,本文对对称加密和分组加密中的几种种模式进行一一分析(ECB、CBC、CFB、OFB,CTR)

    电码本模式 Electronic Codebook Book (ECB)

    概述

      这种模式是将整个明文分成若干段相同的小段,然后对每一小段进行加密。

    特点分析

    优点:

      • 简单;
      • 有利于并行计算;
      • 误差不会被传送;

    缺点:

      • 不能隐藏明文的模式;
      • 可能对明文进行主动攻击;

    代码演示

    /**
    *@autho stardust
    *@time 2013-10-10
    *@param 实现AES五种加密模式的测试
    */
    #include <iostream>
    using namespace std;
    
    //加密编码过程函数,16位1和0
    int dataLen = 16;   //需要加密数据的长度
    int encLen = 4;     //加密分段的长度
    int encTable[4] = {1,0,1,0};  //置换表
    int data[16] = {1,0,0,1,0,0,0,1,1,1,1,1,0,0,0,0}; //明文
    int ciphertext[16]; //密文
    
    //切片加密函数
    void encode(int arr[])
    {
        for(int i=0;i<encLen;i++)
        {
            arr[i] = arr[i] ^ encTable[i];
        }
    }
    
    //电码本模式加密,4位分段
    void ECB(int arr[])
    {
        //数据明文切片
        int a[4][4];
        int dataCount = 0;  //位置变量
        for(int k=0;k<4;k++)
        {
            for(int t=0;t<4;t++)
            {
                a[k][t] = data[dataCount];
                dataCount++;
            }
        }
        dataCount = 0;//重置位置变量
        for(int i=0;i<dataLen;i=i+encLen)
        {
            int r = i/encLen;//
            int l = 0;//
            int encQue[4]; //编码片段
            for(int j=0;j<encLen;j++)
            {
                encQue[j] = a[r][l];
                l++;
            }
            encode(encQue); //切片加密
            //添加到密文表中
            for(int p=0;p<encLen;p++)
            {
                ciphertext[dataCount] = encQue[p];
                dataCount++;
            }
        }
        cout<<"ECB加密的密文为:"<<endl;
        for(int t1=0;t1<dataLen;t1++) //输出密文
        {
            if(t1!=0 && t1%4==0)
                cout<<endl;
            cout<<ciphertext[t1]<<" ";
        }
        cout<<endl;
        cout<<"---------------------------------------------"<<endl;
    }

    密码分组链接模式 Cipher Block Chaining (CBC)

    概述

    这种模式是先将明文切分成若干小段,然后每一小段与初始块或者上一段的密文段进行异或运算后,再与密钥进行加密。

    特点分析

    优点:

      • 不容易主动攻击,安全性好于ECB,适合传输长度长的报文,是SSL、IPSec的标准。

    缺点:

      • 不利于并行计算;
      • 误差传递;
      • 需要初始化向量IV

    代码演示

    #include <iostream>
    using namespace std;
    
    //加密编码过程函数,16位1和0
    int dataLen = 16;   //需要加密数据的长度
    int encLen = 4;     //加密分段的长度
    int encTable[4] = {1,0,1,0};  //置换表
    int data[16] = {1,0,0,1,0,0,0,1,1,1,1,1,0,0,0,0}; //明文
    int ciphertext[16]; //密文
    
    //切片加密函数
    void encode(int arr[])
    {
        for(int i=0;i<encLen;i++)
        {
            arr[i] = arr[i] ^ encTable[i];
        }
    }
    //CBC
    //密码分组链接模式,4位分段
    void CBC(int arr[])
    {
        //数据明文切片
        int a[4][4];
        int dataCount = 0;  //位置变量
        for(int k=0;k<4;k++)
        {
            for(int t=0;t<4;t++)
            {
                a[k][t] = data[dataCount];
                dataCount++;
            }
        }
        dataCount = 0;//重置位置变量
    
        int init[4] = {1,1,0,0};  //初始异或运算输入
        //初始异或运算
        for(int i=0;i<dataLen;i=i+encLen)
        {
            int r = i/encLen;//
            int l = 0;//
            int encQue[4]; //编码片段
            //初始化异或运算
            for(int k=0;k<encLen;k++)
            {
                a[r][k] = a[r][k] ^ init[k];
            }
             //与Key加密的单切片
            for(int j=0;j<encLen;j++)
            {
                encQue[j] = a[r][j];
            }
            encode(encQue); //切片加密
            //添加到密文表中
            for(int p=0;p<encLen;p++)
            {
                ciphertext[dataCount] = encQue[p];
                dataCount++;
            }
            //变换初始输入
            for(int t=0;t<encLen;t++)
            {
                init[t] = encQue[t];
            }
        }
    
    
        cout<<"CCB加密的密文为:"<<endl;
        for(int t1=0;t1<dataLen;t1++) //输出密文
        {
            if(t1!=0 && t1%4==0)
                cout<<endl;
            cout<<ciphertext[t1]<<" ";
        }
        cout<<endl;
        cout<<"---------------------------------------------"<<endl;
    }
    //CBC
    //密码分组链接模式,4位分段
    void CCB(int arr[])
    {
        //数据明文切片
        int a[4][4];
        int dataCount = 0;  //位置变量
        for(int k=0;k<4;k++)
        {
            for(int t=0;t<4;t++)
            {
                a[k][t] = data[dataCount];
                dataCount++;
            }
        }
        dataCount = 0;//重置位置变量
    
        int init[4] = {1,1,0,0};  //初始异或运算输入
        //初始异或运算
        for(int i=0;i<dataLen;i=i+encLen)
        {
            int r = i/encLen;//
            int l = 0;//
            int encQue[4]; //编码片段
            //初始化异或运算
            for(int k=0;k<encLen;k++)
            {
                a[r][k] = a[r][k] ^ init[k];
            }
             //与Key加密的单切片
            for(int j=0;j<encLen;j++)
            {
                encQue[j] = a[r][j];
            }
            encode(encQue); //切片加密
            //添加到密文表中
            for(int p=0;p<encLen;p++)
            {
                ciphertext[dataCount] = encQue[p];
                dataCount++;
            }
            //变换初始输入
            for(int t=0;t<encLen;t++)
            {
                init[t] = encQue[t];
            }
        }
    
    
        cout<<"CCB加密的密文为:"<<endl;
        for(int t1=0;t1<dataLen;t1++) //输出密文
        {
            if(t1!=0 && t1%4==0)
                cout<<endl;
            cout<<ciphertext[t1]<<" ";
        }
        cout<<endl;
        cout<<"---------------------------------------------"<<endl;
    }

    计算器模式Counter (CTR)

    概述

      计算器模式不常见,在CTR模式中, 有一个自增的算子,这个算子用密钥加密之后的输出和明文异或的结果得到密文,相当于一次一密。这种加密方式简单快速,安全可靠,而且可以并行加密,但是 在计算器不能维持很长的情况下,密钥只能使用一次 。CTR的示意图如下所示:

    特点分析

    优点:

    • 无填
    • 同明文不同密
    • 每个块单独运算,适合并行运算。

    缺点:

    • 可能导致明文攻击。

    代码演示

    #include <iostream>
    using namespace std;
    
    //加密编码过程函数,16位1和0
    int dataLen = 16;   //需要加密数据的长度
    int encLen = 4;     //加密分段的长度
    int encTable[4] = {1,0,1,0};  //置换表
    int data[16] = {1,0,0,1,0,0,0,1,1,1,1,1,0,0,0,0}; //明文
    int ciphertext[16]; //密文
    
    //切片加密函数
    void encode(int arr[])
    {
        for(int i=0;i<encLen;i++)
        {
            arr[i] = arr[i] ^ encTable[i];
        }
    }
    //CTR
    //计算器模式,4位分段
    void CTR(int arr[])
    {
        //数据明文切片
        int a[4][4];
        int dataCount = 0;  //位置变量
        for(int k=0;k<4;k++)
        {
            for(int t=0;t<4;t++)
            {
                a[k][t] = data[dataCount];
                dataCount++;
            }
        }
        dataCount = 0;//重置位置变量
    
        int init[4][4] = {{1,0,0,0},{0,0,0,1},{0,0,1,0},{0,1,0,0}};  //算子表
        int l = 0; //明文切片表列
        //初始异或运算
        for(int i=0;i<dataLen;i=i+encLen)
        {
            int r = i/encLen;//
            int encQue[4]; //编码片段
            //将算子切片
            for(int t=0;t<encLen;t++)
            {
                encQue[t] = init[r][t];
            }
            encode(encQue); //算子与key加密
            //最后的异或运算
            for(int k=0;k<encLen;k++)
            {
                encQue[k] = encQue[k] ^ a[l][k];
            }
            l++;
    
            //添加到密文表中
            for(int p=0;p<encLen;p++)
            {
                ciphertext[dataCount] = encQue[p];
                dataCount++;
            }
        }
    
    
        cout<<"CTR加密的密文为:"<<endl;
        for(int t1=0;t1<dataLen;t1++) //输出密文
        {
            if(t1!=0 && t1%4==0)
                cout<<endl;
            cout<<ciphertext[t1]<<" ";
        }
        cout<<endl;
        cout<<"---------------------------------------------"<<endl;
    }

    密码反馈模式(Cipher FeedBack (CFB)

    概述

    特点分析

    优点:

    • 隐藏了明文模式;
    • 分组密码转化为流模式;
    • 可以及时加密传送小于分组的数据;

    缺点:

    • 不利于并行计算;
    • 误差传送:一个明文单元损坏影响多个单元;
    • 唯一的IV;。

    代码演示

    /**
    *@autho stardust
    *@time 2013-10-10
    *@param 实现AES五种加密模式的测试
    */
    #include <iostream>
    using namespace std;
    
    //加密编码过程函数,16位1和0
    int dataLen = 16;   //需要加密数据的长度
    int encLen = 4;     //加密分段的长度
    int encTable[4] = {1,0,1,0};  //置换表
    int data[16] = {1,0,0,1,0,0,0,1,1,1,1,1,0,0,0,0}; //明文
    int ciphertext[16]; //密文
    
    //切片加密函数
    void encode(int arr[])
    {
        for(int i=0;i<encLen;i++)
        {
            arr[i] = arr[i] ^ encTable[i];
        }
    }
    //CFB
    //密码反馈模式,4位分段
    void CFB(int arr[])
    {
        //数据明文切片,切成2 * 8 片
        int a[8][2];
        int dataCount = 0;  //位置变量
        for(int k=0;k<8;k++)
        {
            for(int t=0;t<2;t++)
            {
                a[k][t] = data[dataCount];
                dataCount++;
            }
        }
        dataCount = 0;  //恢复初始化设置
        int lv[4] = {1,0,1,1};  //初始设置的位移变量
        int encQue[2]; //K的高两位
        int k[4]; //K
    
        for(int i=0;i<2 * encLen;i++) //外层加密循环
        {
            //产生K
            for(int vk=0;vk<encLen;vk++)
            {
                k[vk] = lv[vk];
            }
            encode(k);
            for(int k2=0;k2<2;k2++)
            {
                encQue[k2] = k[k2];
            }
            //K与数据明文异或产生密文
            for(int j=0;j<2;j++)
            {
                ciphertext[dataCount] = a[dataCount/2][j] ^ encQue[j];
                dataCount++;
            }
            //lv左移变换
            lv[0] = lv[2];
            lv[1] = lv[3];
            lv[2] = ciphertext[dataCount-2];
            lv[3] = ciphertext[dataCount-1];
        }
    
        cout<<"CFB加密的密文为:"<<endl;
        for(int t1=0;t1<dataLen;t1++) //输出密文
        {
            if(t1!=0 && t1%4==0)
                cout<<endl;
            cout<<ciphertext[t1]<<" ";
        }
        cout<<endl;
        cout<<"---------------------------------------------"<<endl;
    }

    输出反馈模式Output FeedBack (OFB)

    概述

    特点分析

    优点:

    • 同明文不同密文,分组密钥转换为流密码。

    缺点:

    • 串行运算不利并行
    • 传输错误可能导致后续传输块错误。

    代码演示

    /**
    *@autho stardust
    *@time 2013-10-10
    *@param 实现AES五种加密模式的测试
    */
    #include <iostream>
    using namespace std;
    
    //加密编码过程函数,16位1和0
    int dataLen = 16;   //需要加密数据的长度
    int encLen = 4;     //加密分段的长度
    int encTable[4] = {1,0,1,0};  //置换表
    int data[16] = {1,0,0,1,0,0,0,1,1,1,1,1,0,0,0,0}; //明文
    int ciphertext[16]; //密文
    
    //切片加密函数
    void encode(int arr[])
    {
        for(int i=0;i<encLen;i++)
        {
            arr[i] = arr[i] ^ encTable[i];
        }
    }
    //OFB
    //输出反馈模式,4位分段
    void OFB(int arr[])
    {
        //数据明文切片,切成2 * 8 片
        int a[8][2];
        int dataCount = 0;  //位置变量
        for(int k=0;k<8;k++)
        {
            for(int t=0;t<2;t++)
            {
                a[k][t] = data[dataCount];
                dataCount++;
            }
        }
        dataCount = 0;  //恢复初始化设置
        int lv[4] = {1,0,1,1};  //初始设置的位移变量
        int encQue[2]; //K的高两位
        int k[4]; //K
    
        for(int i=0;i<2 * encLen;i++) //外层加密循环
        {
            //产生K
            for(int vk=0;vk<encLen;vk++)
            {
                k[vk] = lv[vk];
            }
            encode(k);
            for(int k2=0;k2<2;k2++)
            {
                encQue[k2] = k[k2];
            }
            //K与数据明文异或产生密文
            for(int j=0;j<2;j++)
            {
                ciphertext[dataCount] = a[dataCount/2][j] ^ encQue[j];
                dataCount++;
            }
            //lv左移变换
            lv[0] = lv[2];
            lv[1] = lv[3];
            lv[2] = encQue[0];
            lv[3] = encQue[1];
        }
    
        cout<<"CFB加密的密文为:"<<endl;
        for(int t1=0;t1<dataLen;t1++) //输出密文
        {
            if(t1!=0 && t1%4==0)
                cout<<endl;
            cout<<ciphertext[t1]<<" ";
        }
        cout<<endl;
        cout<<"---------------------------------------------"<<endl;
    }
  • 相关阅读:
    SAP分析云及协同计划
    使用SSH命令行远程登录运行在CloudFoundry上的应用
    如何远程调试部署在CloudFoundry平台上的nodejs应用
    Apache httpclient的execute方法调试
    如何用Java代码在SAP Marketing Cloud里创建contact数据
    nodejs request module里的json参数的一个坑
    如何在调用Marketing Cloud contact创建API时增加对扩展字段的支持
    Efim and Strange Grade
    Vitya in the Countryside
    Anatoly and Cockroaches
  • 原文地址:https://www.cnblogs.com/shawWey/p/8425663.html
Copyright © 2011-2022 走看看