密码之AES五种加密模式(CBC、ECB、CTR、OCF、CFB)

转:https://www.cnblogs.com/starwolf/p/3365834.html

分组密码有五种工作体制:

1.电码本模式(Electronic Codebook Book (ECB));

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

3.计算器模式(Counter (CTR));

4.密码反馈模式(Cipher FeedBack (CFB));

5.输出反馈模式(Output FeedBack (OFB))。

以下逐一介绍一下:

1.电码本模式(Electronic Codebook Book (ECB)

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

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

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

3.计算器模式(Counter (CTR))

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

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

5.输出反馈模式(Output FeedBack (OFB))

这种模式较复杂。

以下附上C++源代码:

/** 

*@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; 

}

      //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;

 }

 //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;

 } 

//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;

 } 

//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; 


void printData()

 { 

    cout<<"以下示范AES五种加密模式的测试结果:"<<endl; 

    cout<<"---------------------------------------------"<<endl; 

    cout<<"明文为:"<<endl; 

    for(int t1=0;t1<dataLen;t1++) //输出密文 

    { if(t1!=0 && t1%4==0) cout<<endl; cout<<data[t1]<<" "; }

     cout<<endl; 

    cout<<"---------------------------------------------"<<endl;

 }

 int main() 

{

     printData();

     ECB(data); 

    CCB(data); 

    CTR(data);

     CFB(data); 

    OFB(data);

     return 0; 

}

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 213,558评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,002评论 3 387
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 159,036评论 0 349
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,024评论 1 285
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,144评论 6 385
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,255评论 1 292
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,295评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,068评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,478评论 1 305
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,789评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,965评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,649评论 4 336
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,267评论 3 318
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,982评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,223评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,800评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,847评论 2 351

推荐阅读更多精彩内容