精华内容
下载资源
问答
  • rijndael算法

    2018-06-21 17:52:09
    Rijndael(读作rain-dahl)是由美国国家标准与技术协会(NIST)所选的高级加密标准(AES)的候选算法,密码学中的rijndael算法
  • rijndael 算法

    2008-03-16 18:41:11
    rijndael 算法
  • Rijndael算法

    2009-05-23 10:07:32
    英文版的Rijndael算法,对需要了解AES的朋友很有用处,可以下来看看
  • visual c++使用Rijndael算法
  • AES简介——Rijndael算法介绍,内容来源于网络内容的整理。是关于C#源码的补充,不了解此内容依旧可以用C#代码实现Rijndael算法
  • AES加密算法(Rijndael算法

    万次阅读 2018-05-09 14:52:32
    此文章为转载,如有侵权,通知删除 ... 上周好几天都在搞AES,总算是把Rijndael算法搞明白了。本片会仔细介绍AES(Rijndael算法),后两篇会介绍AES的java和php实现。...AES(Rijndael算法) ...Rijndael算法

    此文章为转载,如有侵权,通知删除

    原地址:https://blog.csdn.net/zfpigpig/article/details/8526016


    上周好几天都在搞AES,总算是把Rijndael算法搞明白了。本片会仔细介绍AES(Rijndael算法),后两篇会介绍AES的java和php实现。

    AES(Rijndael算法)

    Rijndael算法首先是一个密钥分组加密的算法,通过置换(permutations )和替换(substitutions)迭代加密,进过多轮操作形成密文。AES算是Rijndael算法的一种特殊实现,选的分组为128bit(16字节),密钥可以使用128、192 和 256bit三种。

    分组

    上面已经说了AES分组为16个字节,下面说说他的排列,其实就是一个4x4的矩阵,不过要注意是竖着排的。

    AES原文:a1a2a3a4 a5a6a7a8 a9a10a11a12 a13a14a15a16...

    a1    a5    a9    a13

    a2    a6    a10  a14

    a3    a7    a11  a15

    a4    a8    a12  a16

    密钥

    AES的密钥虽然有三种,但是并不意味着这三种密钥的AES差异很大,相反加密过程其实完全一样,只是种子密钥是128,192,256bit三种而已。密钥在AES与分组数据并没有做非常复杂的变化,其实只是简单的&(与)操作而已。不过又因为AES算法有很多轮,所有单单的种子密钥是不够的,所有AES有自己的扩展密钥的方法。还要提一下,密钥扩展后也是竖着排成方阵的。

    key:k1k2k3k4 k5k6k7k8 k9k10k11k12 k13k14k15k16...

    k1    k5    k9    k13

    k2    k6    k10  k14

    k3    k7    k11  k15

    k4    k8    k12  k16

    轮数

    轮数主要跟种子密钥长度有关。

    一般习惯用Nk表示密钥所含的数据字数,一字表示32bit,也就是4字节,也就是一竖排。

    128,192,256bit对应Nk=4,6,8

    一般习惯用Nr表示轮数

    Nr = Nk+6也就是10,12,14

    密钥扩展(KeyExpansion)

    对与密钥扩展其实只要关心两点:一是扩展成多长,这个其实跟加密过程有关,暂时只要知道密钥总长度为(分组大小=16个字节)*(Nr+1),也就是4*(Nr+1)字,下面讲过程的时候就会明白为什么要这么长。二是密钥扩展的算法,密钥的算法其实比较复杂,但是却不难理解。

    注:Nk密钥字数,字为4字节也就是一竖排。

    算法步骤如下:

    Nk ≤ 6 的密钥扩展

    1)最前面的 Nk 个字是由种子密钥填充的。
    2)之后的每一个字 W[j] 等于前面的字 W[j-1] 的与 Nk 个位置之前的字 W[j-Nk]的异或。
    3)而且对于 Nk 的整数倍的位置处的字,在异或之前,对 W[j-1] 的进行如下变换:
          .字节的循环移位 RotByte->即当输入字为 (a,b,c,d) 时,输出字为 (b , c, d, a )
          .用 S 盒进行变换次位元组
          .异或轮常数 Rcon[i/Nk]

    伪代码

    KeyExpansion (byteKey[4*Nk] , W[Nb*(Nr+1)])
    {
        for (i =0; i < Nk; i ++)
            W[i]=(Key[4* i],Key[4* i +1],Key[4* i +2],Key[4* i +3] );
    //扩展密钥的前面4个字由种子密钥组成
    
        for (i =Nk; i <Nb*(Nr+1); i ++)
        {
            temp=W[i-1];
            if (i % Nk= =0)             
       temp=SubByte (RotByte (temp))^Rcon[i /Nk];
            //i是NK的整数倍是要特殊处理
           W[i]=W[i-Nk]^ temp;
        }
    }


    Nk > 6 的密钥扩展

    KeyExpansion (byte  Key[4*Nk] , W[Nb*(Nr+1)])
    {
            for (i=0; i < Nk; i ++)
            W[i]=(Key[4* i], Key[4* i +1], Key[4* i +2], Key[4* i +3] );
     //扩展密钥的前面4个字由种子密钥组成
    for (i =Nk; i <Nb*(Nr+1); i ++)
        {
            temp=W[i -1];
            if (i % Nk= =0)
                temp=SubByte (RotByte (temp))^Rcon[i /Nk];
        //i是NK的整数倍是要特殊处理
             else if (i % Nk==4)
                     temp=SubByte (temp);
         //i是4的整数倍是要特殊处理
            W[i]=W[i - Nk]^ temp;
        }
    }


    异或轮常数 Rcon[i/Nk] :Rcon[i/Nk]=(RC[i/Nk]],’00’,’00’,’00’)(i一定会大于Nk)
                                              RC[1]=‘01’
                                              RC[x]=2⊙RC[x-1]

    (其实我也不懂Rcon,不过有人已经算好了如下

    RC[1]=(01, 00, 00, 00),
    RC[2]=(02, 00, 00, 00),
    RC[3]=(04, 00, 00, 00),
    RC[4]=(08, 00, 00, 00),
    RC[5]=(10, 00, 00, 00),
    RC[6]=(20, 00, 00, 00),
    RC[7]=(40, 00, 00, 00),
    RC[8]=(80, 00, 00, 00),
    RC[9]=(1b, 00, 00, 00),
    RC[10]=(36, 00, 00, 00))


    到此准备工作就完成了

    接下来就是真正的加密流程

    每一轮分组(源数据)都要经过4种变换,分别是ByteSub ShiftRow MixColumn AddRoundKey

    ByteSub(字节代换)

    这个比较简单,就是查表替代。对于分组的16字节都进行字节代换就行,还有字节一般写成16进制的也就是如FF这种。sbox如下图:


    ShiftRow(行移位)

    对于分组4x4有4行,进行如下规则位移

    第 0 行不移位,

    第1行左移1字节,

    第2行左移2字节,

    第3行左移3字节。

    MixColumn (列混合)

    列混合其实比较难理解。原理是数学矩阵相乘,如下图s为原数据,s‘为加密后数据。


    不过这里的乘法和加法都是数学域操作,说白了就是一种新的运算。

    加法

    a+b=a^b

    加法就是做两者的异或操作

    乘法

    0x01*b=b

    0x02*b 只要b小于0x80,b<<1。如果b大于或等于0x80,(b<<1)^0x1b

    对于大于0x02可以分解成0x02和0x01的算法,这牵扯到数学域GF(2 ^8),可以分解成2的幂次方,在这不多做介绍,其实是本文作者能力有限,讲不清楚。

    b * 0x03 = b * (0x02 + 0x01)
             = (b * 0x02) + (b * 0x01)
    
    b * 0x0d = b * (0x08 + 0x04 + 0x01)
             = (b * 0x08) + (b * 0x04) + (b * 0x01)
             = (b * 0x02 * 0x02 * 0x02) + (b * 0x02 * 0x02) + (b * 0x01)
    
    b * 0x09 = b * (0x08 + 0x01)
             = (b * 0x02 * 0x02 * 0x02) + (b * 0x01)
    b * 0x0b = b * (0x08 + 0x02 + 0x01)
             = (b * 0x02 * 0x02 * 0x02) + (b * 0x02) + (b * 0x01)
    b * 0x0e = b * (0x08 + 0x04 + 0x02)
            = (b * 0x02 * 0x02 * 0x02) + (b * 0x02 * 0x02) + (b * 0x02)

    AddRoundKey

    就是4x4的原数据与4x4的扩展密钥做异或运算


    下面是加密流程的伪代码,到此aes算法就介绍完了

    Encryption(State,CipherKey)
     {    KeyExpansion(CipherKey, RoundKey)
    
    
          AddRoundKey(State, RoundKey)//第0轮只做AddRoundKey
    
    
          For(i=1;i<Nr;i++)
          Round(State, RoundKey)
              {ByteSub(State);
                ShiftRow(State);
                MixColumn(State);
                AddRoundKey(State, RoundKey)}
    
    
           FinalRound(State, RoundKey)//最后一轮不做mixcolumn
              { ByteSub(State);
                 ShiftRow(State); 
                 AddRoundKey(State, RoundKey);}
    }    
    
    
    
    


    展开全文
  • AES(Rijndael算法

    千次阅读 2017-07-01 12:06:00
    上周好几天都在搞AES,总算是把Rijndael算法搞明白了。本篇会仔细介绍AES(Rijndael算法),后两篇会介绍AES的Java和PHP实现。AES(Rijndael算法Rijndael算法首先是一个密钥分组加密的算法,通过置换...

    上周好几天都在搞AES,总算是把Rijndael算法搞明白了。本篇会仔细介绍AES(Rijndael算法),后两篇会介绍AES的Java和PHP实现。

    AES(Rijndael算法)

    Rijndael算法首先是一个密钥分组加密的算法,通过置换(permutations )和替换(substitutions)迭代加密,进过多轮操作形成密文。AES算是Rijndael算法的一种特殊实现,选的分组为128bit(16字节),密钥可以使用128、192 和 256bit三种。

    分组

    上面已经说了AES分组为16个字节,下面说说他的排列,其实就是一个4x4的矩阵,不过要注意是竖着排的。
    AES原文:a1a2a3a4 a5a6a7a8 a9a10a11a12 a13a14a15a16…

    a1    a5    a9    a13
    
    a2    a6    a10  a14
    
    a3    a7    a11  a15
    
    a4    a8    a12  a16

    密钥

    AES的密钥虽然有三种,但是并不意味着这三种密钥的AES差异很大,相反加密过程其实完全一样,只是种子密钥是128,192,256bit三种而已。密钥在AES与分组数据并没有做非常复杂的变化,其实只是简单的&(与)操作而已。不过又因为AES算法有很多轮,所有单单的种子密钥是不够的,所有AES有自己的扩展密钥的方法。还要提一下,密钥扩展后也是竖着排成方阵的。

    key:k1k2k3k4 k5k6k7k8 k9k10k11k12 k13k14k15k16…

    k1    k5    k9    k13
    
    k2    k6    k10  k14
    
    k3    k7    k11  k15
    
    k4    k8    k12  k16

    轮数

    轮数主要跟种子密钥长度有关。

    一般习惯用Nk表示密钥所含的数据字数,一字表示32bit,也就是4字节,也就是一竖排。

    128,192,256bit对应Nk=4,6,8

    一般习惯用Nr表示轮数

    Nr = Nk+6也就是10,12,14

    密钥扩展(KeyExpansion)

    对与密钥扩展其实只要关心两点:一是扩展成多长,这个其实跟加密过程有关,暂时只要知道密钥总长度为(分组大小=16个字节)(Nr+1),也就是4(Nr+1)字,下面讲过程的时候就会明白为什么要这么长。二是密钥扩展的算法,密钥的算法其实比较复杂,但是却不难理解。

    注:Nk密钥字数,字为4字节也就是一竖排。

    算法步骤如下:

    Nk ≤ 6 的密钥扩展

    1)最前面的 Nk 个字是由种子密钥填充的。
    2)之后的每一个字 W[j] 等于前面的字 W[j-1] 的与 Nk 个位置之前的字 W[j-Nk]的异或。
    3)而且对于 Nk 的整数倍的位置处的字,在异或之前,对 W[j-1] 的进行如下变换:
    .字节的循环移位 RotByte->即当输入字为 (a,b,c,d) 时,输出字为 (b , c, d, a )
    .用 S 盒进行变换次位元组
    .异或轮常数 Rcon[i/Nk]

    伪代码

    KeyExpansion (byteKey[4*Nk] , W[Nb*(Nr+1)])
    {
        for (i =0; i < Nk; i ++)
            W[i]=(Key[4* i],Key[4* i +1],Key[4* i +2],Key[4* i +3] );
    //扩展密钥的前面4个字由种子密钥组成
    
        for (i =Nk; i <Nb*(Nr+1); i ++)
        {
            temp=W[i-1];
            if (i % Nk= =0)             
       temp=SubByte (RotByte (temp))^Rcon[i /Nk];
            //iNK的整数倍是要特殊处理
           W[i]=W[i-Nk]^ temp;
        }
    }

    Nk > 6 的密钥扩展

    KeyExpansion (byte  Key[4*Nk] , W[Nb*(Nr+1)])
    {
            for (i=0; i < Nk; i ++)
            W[i]=(Key[4* i], Key[4* i +1], Key[4* i +2], Key[4* i +3] );
     //扩展密钥的前面4个字由种子密钥组成
    for (i =Nk; i <Nb*(Nr+1); i ++)
        {
            temp=W[i -1];
            if (i % Nk= =0)
                temp=SubByte (RotByte (temp))^Rcon[i /Nk];
        //i是NK的整数倍是要特殊处理
             else if (i % Nk==4)
                     temp=SubByte (temp);
         //i是4的整数倍是要特殊处理
            W[i]=W[i - Nk]^ temp;
        }
    }

    异或轮常数 Rcon[i/Nk] :

    Rcon[i/Nk]=(RC[i/Nk]],’00’,’00’,’00’)(i一定会大于NkRC[1]=‘01’
                                              RC[x]=2⊙RC[x-1]

    (其实我也不懂Rcon,不过有人已经算好了如下

    RC[1]=(01, 00, 00, 00),
    RC[2]=(02, 00, 00, 00),
    RC[3]=(04, 00, 00, 00),
    RC[4]=(08, 00, 00, 00),
    RC[5]=(10, 00, 00, 00),
    RC[6]=(20, 00, 00, 00),
    RC[7]=(40, 00, 00, 00),
    RC[8]=(80, 00, 00, 00),
    RC[9]=(1b, 00, 00, 00),
    RC[10]=(36, 00, 00, 00))

    到此准备工作就完成了

    接下来就是真正的加密流程

    每一轮分组(源数据)都要经过4种变换,分别是ByteSub ShiftRow MixColumn AddRoundKey

    ByteSub(字节代换)

    这个比较简单,就是查表替代。对于分组的16字节都进行字节代换就行,还有字节一般写成16进制的也就是如FF这种。sbox如下图:
    这里写图片描述

    ShiftRow(行移位)

    对于分组4x4有4行,进行如下规则位移

    第 0 行不移位,

    第1行左移1字节,

    第2行左移2字节,

    第3行左移3字节。

    MixColumn (列混合)

    列混合其实比较难理解。原理是数学矩阵相乘,如下图s为原数据,s‘为加密后数据。
    这里写图片描述
    不过这里的乘法和加法都是数学域操作,说白了就是一种新的运算。

    加法

    a+b=a^b

    加法就是做两者的异或操作

    乘法

    0x01*b=b

    0x02*b 只要b小于0x80,b<<1。如果b大于或等于0x80,(b<<1)^0x1b

    对于大于0x02可以分解成0x02和0x01的算法,这牵扯到数学域GF(2 ^8),可以分解成2的幂次方,在这不多做介绍,其实是本文作者能力有限,讲不清楚。

    b * 0x03 = b * (0x02 + 0x01)
             = (b * 0x02) + (b * 0x01)
    
    b * 0x0d = b * (0x08 + 0x04 + 0x01)
             = (b * 0x08) + (b * 0x04) + (b * 0x01)
             = (b * 0x02 * 0x02 * 0x02) + (b * 0x02 * 0x02) + (b * 0x01)
    
    b * 0x09 = b * (0x08 + 0x01)
             = (b * 0x02 * 0x02 * 0x02) + (b * 0x01)
    b * 0x0b = b * (0x08 + 0x02 + 0x01)
             = (b * 0x02 * 0x02 * 0x02) + (b * 0x02) + (b * 0x01)
    b * 0x0e = b * (0x08 + 0x04 + 0x02)
             = (b * 0x02 * 0x02 * 0x02) + (b * 0x02 * 0x02) + (b * 0x02)

    AddRoundKey

    就是4x4的原数据与4x4的扩展密钥做异或运算

    下面是加密流程的伪代码,到此aes算法就介绍完了

    Encryption(State,CipherKey)
     {    KeyExpansion(CipherKey, RoundKey)
    
    
          AddRoundKey(State, RoundKey)//第0轮只做AddRoundKey
    
    
          For(i=1;i<Nr;i++)
          Round(State, RoundKey)
              {ByteSub(State);
                ShiftRow(State);
                MixColumn(State);
                AddRoundKey(State, RoundKey)}
    
    
           FinalRound(State, RoundKey)//最后一轮不做mixcolumn
              { ByteSub(State);
                 ShiftRow(State);
                 AddRoundKey(State, RoundKey);}
    }   
    展开全文
  • 文件为C语言源代码,实现了AES加解密算法中的Rijndael算法。支持密钥长度为128bit、192bit和256bit,明文分组长度为128bit、192bit和256bit,密钥和明文(密文)可两两组合(使用者在测试程序的main函数中自行调整)...
  • 现代的加密算法都是基于密钥的,然而,迄今为止,很少有人研究Rijndael算法的密钥调度部分,尤其是如何生成Rijndael算法初始密钥,针对这一情况,研究了混沌Logistic映射,利用Logistic映射产生的混沌序列的高随机性...
  • AES_Rijndael算法协处理器设计与实现.pdf
  • 【算法】AES(Rijndael算法

    万次阅读 2013-01-23 20:03:08
    上周好几天都在搞AES,总算是把Rijndael算法搞明白了。本片会仔细介绍AES(Rijndael算法),后两篇会介绍AES的java和php实现。 AES(Rijndael算法Rijndael算法首先是一个密钥分组加密的算法,通过置换...

    上周好几天都在搞AES,总算是把Rijndael算法搞明白了。本片会仔细介绍AES(Rijndael算法),后两篇会介绍AES的java和php实现。

    AES(Rijndael算法)

    Rijndael算法首先是一个密钥分组加密的算法,通过置换(permutations )和替换(substitutions)迭代加密,进过多轮操作形成密文。AES算是Rijndael算法的一种特殊实现,选的分组为128bit(16字节),密钥可以使用128、192 和 256bit三种。

    分组

    上面已经说了AES分组为16个字节,下面说说他的排列,其实就是一个4x4的矩阵,不过要注意是竖着排的。

    AES原文:a1a2a3a4 a5a6a7a8 a9a10a11a12 a13a14a15a16...

    a1    a5    a9    a13

    a2    a6    a10  a14

    a3    a7    a11  a15

    a4    a8    a12  a16

    密钥

    AES的密钥虽然有三种,但是并不意味着这三种密钥的AES差异很大,相反加密过程其实完全一样,只是种子密钥是128,192,256bit三种而已。密钥在AES与分组数据并没有做非常复杂的变化,其实只是简单的&(与)操作而已。不过又因为AES算法有很多轮,所有单单的种子密钥是不够的,所有AES有自己的扩展密钥的方法。还要提一下,密钥扩展后也是竖着排成方阵的。

    key:k1k2k3k4 k5k6k7k8 k9k10k11k12 k13k14k15k16...

    k1    k5    k9    k13

    k2    k6    k10  k14

    k3    k7    k11  k15

    k4    k8    k12  k16

    轮数

    轮数主要跟种子密钥长度有关。

    一般习惯用Nk表示密钥所含的数据字数,一字表示32bit,也就是4字节,也就是一竖排。

    128,192,256bit对应Nk=4,6,8

    一般习惯用Nr表示轮数

    Nr = Nk+6也就是10,12,14

    密钥扩展(KeyExpansion)

    对与密钥扩展其实只要关心两点:一是扩展成多长,这个其实跟加密过程有关,暂时只要知道密钥总长度为(分组大小=16个字节)*(Nr+1),也就是4*(Nr+1)字,下面讲过程的时候就会明白为什么要这么长。二是密钥扩展的算法,密钥的算法其实比较复杂,但是却不难理解。

    注:Nk密钥字数,字为4字节也就是一竖排。

    算法步骤如下:

    Nk ≤ 6 的密钥扩展

    1)最前面的 Nk 个字是由种子密钥填充的。
    2)之后的每一个字 W[j] 等于前面的字 W[j-1] 的与 Nk 个位置之前的字 W[j-Nk]的异或。
    3)而且对于 Nk 的整数倍的位置处的字,在异或之前,对 W[j-1] 的进行如下变换:
          .字节的循环移位 RotByte->即当输入字为 (a,b,c,d) 时,输出字为 (b , c, d, a )
          .用 S 盒进行变换次位元组
          .异或轮常数 Rcon[i/Nk]

    伪代码

    KeyExpansion (byteKey[4*Nk] , W[Nb*(Nr+1)])
    {
        for (i =0; i < Nk; i ++)
            W[i]=(Key[4* i],Key[4* i +1],Key[4* i +2],Key[4* i +3] );
    //扩展密钥的前面4个字由种子密钥组成

        for (i =Nk; i <Nb*(Nr+1); i ++)
        {
            temp=W[i-1];
            if (i % Nk= =0)             
       temp=SubByte (RotByte (temp))^Rcon[i /Nk];
            //i是NK的整数倍是要特殊处理
           W[i]=W[i-Nk]^ temp;
        }
    }

    Nk > 6 的密钥扩展

    KeyExpansion (byte  Key[4*Nk] , W[Nb*(Nr+1)])
    {
            for (i=0; i < Nk; i ++)
            W[i]=(Key[4* i], Key[4* i +1], Key[4* i +2], Key[4* i +3] );
     //扩展密钥的前面4个字由种子密钥组成
    for (i =Nk; i <Nb*(Nr+1); i ++)
        {
            temp=W[i -1];
            if (i % Nk= =0)
                temp=SubByte (RotByte (temp))^Rcon[i /Nk];
        //i是NK的整数倍是要特殊处理
             else if (i % Nk==4)
                     temp=SubByte (temp);
         //i是4的整数倍是要特殊处理
            W[i]=W[i - Nk]^ temp;
        }
    }

    异或轮常数 Rcon[i/Nk] :Rcon[i/Nk]=(RC[i/Nk]],’00’,’00’,’00’)(i一定会大于Nk)
                                              RC[1]=‘01’
                                              RC[x]=2⊙RC[x-1]

    (其实我也不懂Rcon,不过有人已经算好了如下

    RC[1]=(01, 00, 00, 00),
    RC[2]=(02, 00, 00, 00),
    RC[3]=(04, 00, 00, 00),
    RC[4]=(08, 00, 00, 00),
    RC[5]=(10, 00, 00, 00),
    RC[6]=(20, 00, 00, 00),
    RC[7]=(40, 00, 00, 00),
    RC[8]=(80, 00, 00, 00),
    RC[9]=(1b, 00, 00, 00),
    RC[10]=(36, 00, 00, 00))


    到此准备工作就完成了

    接下来就是真正的加密流程

    每一轮分组(源数据)都要经过4种变换,分别是ByteSub ShiftRow MixColumn AddRoundKey

    ByteSub(字节代换)

    这个比较简单,就是查表替代。对于分组的16字节都进行字节代换就行,还有字节一般写成16进制的也就是如FF这种。sbox如下图:


    ShiftRow(行移位)

    对于分组4x4有4行,进行如下规则位移

    第 0 行不移位,

    第1行左移1字节,

    第2行左移2字节,

    第3行左移3字节。

    MixColumn (列混合)

    列混合其实比较难理解。原理是数学矩阵相乘,如下图s为原数据,s‘为加密后数据。


    不过这里的乘法和加法都是数学域操作,说白了就是一种新的运算。

    加法

    a+b=a^b

    加法就是做两者的异或操作

    乘法

    0x01*b=b

    0x02*b 只要b小于0x80,b<<1。如果b大于或等于0x80,(b<<1)^0x1b

    对于大于0x02可以分解成0x02和0x01的算法,这牵扯到数学域GF(2 ^8),可以分解成2的幂次方,在这不多做介绍,其实是本文作者能力有限,讲不清楚。

    b * 0x03 = b * (0x02 + 0x01)
             = (b * 0x02) + (b * 0x01)
    
    b * 0x0d = b * (0x08 + 0x04 + 0x01)
             = (b * 0x08) + (b * 0x04) + (b * 0x01)
             = (b * 0x02 * 0x02 * 0x02) + (b * 0x02 * 0x02) + (b * 0x01)
    
    b * 0x09 = b * (0x08 + 0x01)
             = (b * 0x02 * 0x02 * 0x02) + (b * 0x01)
    b * 0x0b = b * (0x08 + 0x02 + 0x01)
             = (b * 0x02 * 0x02 * 0x02) + (b * 0x02) + (b * 0x01)
    b * 0x0e = b * (0x08 + 0x04 + 0x02)
            = (b * 0x02 * 0x02 * 0x02) + (b * 0x02 * 0x02) + (b * 0x02)

    AddRoundKey

    就是4x4的原数据与4x4的扩展密钥做异或运算


    下面是加密流程的伪代码,到此aes算法就介绍完了

    Encryption(State,CipherKey)
     {    KeyExpansion(CipherKey, RoundKey)


          AddRoundKey(State, RoundKey)//第0轮只做AddRoundKey


          For(i=1;i<Nr;i++)
          Round(State, RoundKey)
              {ByteSub(State);
                ShiftRow(State);
                MixColumn(State);
                AddRoundKey(State, RoundKey)}


           FinalRound(State, RoundKey)//最后一轮不做mixcolumn
              { ByteSub(State);
                 ShiftRow(State);
                 AddRoundKey(State, RoundKey);}
    }   

    展开全文
  • 通过深入分析Rijndael算法,改进了AES算法的几个有可能产生不安全隐患的步骤。首先是对于最可能被攻击的混列进行优化,使该步骤变成简单的查表而不是域乘,增加了非线形安全性;其次对于子密钥的生成方面引入了随机...
  • Rijndael算法的Java实现

    热门讨论 2011-11-16 03:44:59
    AES加密,Rijndael算法,用Java语言实现的源代码,供各位参考!
  • 原文地址:https://blog.csdn.net/zfpigpig/article/details/8526016上周好几天都在搞AES,总算是把Rijndael...AES(Rijndael算法Rijndael算法首先是一个密钥分组加密的算法,通过置换(permutations )和替换(sub...

    原文地址:

    https://blog.csdn.net/zfpigpig/article/details/8526016

    上周好几天都在搞AES,总算是把Rijndael算法搞明白了。本片会仔细介绍AES(Rijndael算法),后两篇会介绍AES的java和php实现。

    AES(Rijndael算法)

    Rijndael算法首先是一个密钥分组加密的算法,通过置换(permutations )和替换(substitutions)迭代加密,进过多轮操作形成密文。AES算是Rijndael算法的一种特殊实现,选的分组为128bit(16字节),密钥可以使用128、192 和 256bit三种。

    分组

    上面已经说了AES分组为16个字节,下面说说他的排列,其实就是一个4x4的矩阵,不过要注意是竖着排的。

    AES原文:a1a2a3a4 a5a6a7a8 a9a10a11a12 a13a14a15a16...

    a1    a5    a9    a13

    a2    a6    a10  a14

    a3    a7    a11  a15

    a4    a8    a12  a16

    密钥

    AES的密钥虽然有三种,但是并不意味着这三种密钥的AES差异很大,相反加密过程其实完全一样,只是种子密钥是128,192,256bit三种而已。密钥在AES与分组数据并没有做非常复杂的变化,其实只是简单的&(与)操作而已。不过又因为AES算法有很多轮,所有单单的种子密钥是不够的,所有AES有自己的扩展密钥的方法。还要提一下,密钥扩展后也是竖着排成方阵的。

    key:k1k2k3k4 k5k6k7k8 k9k10k11k12 k13k14k15k16...

    k1    k5    k9    k13

    k2    k6    k10  k14

    k3    k7    k11  k15

    k4    k8    k12  k16

    轮数

    轮数主要跟种子密钥长度有关。

    一般习惯用Nk表示密钥所含的数据字数,一字表示32bit,也就是4字节,也就是一竖排。

    128,192,256bit对应Nk=4,6,8

    一般习惯用Nr表示轮数

    Nr = Nk+6也就是10,12,14

    密钥扩展(KeyExpansion)

    对与密钥扩展其实只要关心两点:一是扩展成多长,这个其实跟加密过程有关,暂时只要知道密钥总长度为(分组大小=16个字节)*(Nr+1),也就是4*(Nr+1)字,下面讲过程的时候就会明白为什么要这么长。二是密钥扩展的算法,密钥的算法其实比较复杂,但是却不难理解。

    注:Nk密钥字数,字为4字节也就是一竖排。

    算法步骤如下:

    Nk ≤ 6 的密钥扩展

    1)最前面的 Nk 个字是由种子密钥填充的。
    2)之后的每一个字 W[j] 等于前面的字 W[j-1] 的与 Nk 个位置之前的字 W[j-Nk]的异或。
    3)而且对于 Nk 的整数倍的位置处的字,在异或之前,对 W[j-1] 的进行如下变换:
          .字节的循环移位 RotByte->即当输入字为 (a,b,c,d) 时,输出字为 (b , c, d, a )
          .用 S 盒进行变换次位元组
          .异或轮常数 Rcon[i/Nk]

    伪代码

    KeyExpansion (byteKey[4*Nk] , W[Nb*(Nr+1)])
    {
        for (i =0; i < Nk; i ++)
            W[i]=(Key[4* i],Key[4* i +1],Key[4* i +2],Key[4* i +3] );
    //扩展密钥的前面4个字由种子密钥组成

        for (i =Nk; i <Nb*(Nr+1); i ++)
        {
            temp=W[i-1];
            if (i % Nk= =0)             
       temp=SubByte (RotByte (temp))^Rcon[i /Nk];
            //i是NK的整数倍是要特殊处理
           W[i]=W[i-Nk]^ temp;
        }
    }

    Nk > 6 的密钥扩展

    KeyExpansion (byte  Key[4*Nk] , W[Nb*(Nr+1)])
    {
            for (i=0; i < Nk; i ++)
            W[i]=(Key[4* i], Key[4* i +1], Key[4* i +2], Key[4* i +3] );
     //扩展密钥的前面4个字由种子密钥组成
    for (i =Nk; i <Nb*(Nr+1); i ++)
        {
            temp=W[i -1];
            if (i % Nk= =0)
                temp=SubByte (RotByte (temp))^Rcon[i /Nk];
        //i是NK的整数倍是要特殊处理
             else if (i % Nk==4)
                     temp=SubByte (temp);
         //i是4的整数倍是要特殊处理
            W[i]=W[i - Nk]^ temp;
        }
    }

    异或轮常数 Rcon[i/Nk] :Rcon[i/Nk]=(RC[i/Nk]],’00’,’00’,’00’)(i一定会大于Nk)
                                              RC[1]=‘01’
                                              RC[x]=2⊙RC[x-1]

    (其实我也不懂Rcon,不过有人已经算好了如下

    RC[1]=(01, 00, 00, 00),
    RC[2]=(02, 00, 00, 00),
    RC[3]=(04, 00, 00, 00),
    RC[4]=(08, 00, 00, 00),
    RC[5]=(10, 00, 00, 00),
    RC[6]=(20, 00, 00, 00),
    RC[7]=(40, 00, 00, 00),
    RC[8]=(80, 00, 00, 00),
    RC[9]=(1b, 00, 00, 00),
    RC[10]=(36, 00, 00, 00))


    到此准备工作就完成了

    接下来就是真正的加密流程

    每一轮分组(源数据)都要经过4种变换,分别是ByteSub ShiftRow MixColumn AddRoundKey

    ByteSub(字节代换)

    这个比较简单,就是查表替代。对于分组的16字节都进行字节代换就行,还有字节一般写成16进制的也就是如FF这种。sbox如下图:


    ShiftRow(行移位)

    对于分组4x4有4行,进行如下规则位移

    第 0 行不移位,

    第1行左移1字节,

    第2行左移2字节,

    第3行左移3字节。

    MixColumn (列混合)

    列混合其实比较难理解。原理是数学矩阵相乘,如下图s为原数据,s‘为加密后数据。


    不过这里的乘法和加法都是数学域操作,说白了就是一种新的运算。

    加法

    a+b=a^b

    加法就是做两者的异或操作

    乘法

    0x01*b=b

    0x02*b 只要b小于0x80,b<<1。如果b大于或等于0x80,(b<<1)^0x1b

    对于大于0x02可以分解成0x02和0x01的算法,这牵扯到数学域GF(2 ^8),可以分解成2的幂次方,在这不多做介绍,其实是本文作者能力有限,讲不清楚。

    b * 0x03 = b * (0x02 + 0x01)
             = (b * 0x02) + (b * 0x01)
    
    b * 0x0d = b * (0x08 + 0x04 + 0x01)
             = (b * 0x08) + (b * 0x04) + (b * 0x01)
             = (b * 0x02 * 0x02 * 0x02) + (b * 0x02 * 0x02) + (b * 0x01)
    
    b * 0x09 = b * (0x08 + 0x01)
             = (b * 0x02 * 0x02 * 0x02) + (b * 0x01)
    b * 0x0b = b * (0x08 + 0x02 + 0x01)
             = (b * 0x02 * 0x02 * 0x02) + (b * 0x02) + (b * 0x01)
    b * 0x0e = b * (0x08 + 0x04 + 0x02)
            = (b * 0x02 * 0x02 * 0x02) + (b * 0x02 * 0x02) + (b * 0x02)

    AddRoundKey

    就是4x4的原数据与4x4的扩展密钥做异或运算


    下面是加密流程的伪代码,到此aes算法就介绍完了

    Encryption(State,CipherKey)
     {    KeyExpansion(CipherKey, RoundKey)


          AddRoundKey(State, RoundKey)//第0轮只做AddRoundKey


          For(i=1;i<Nr;i++)
          Round(State, RoundKey)
              {ByteSub(State);
                ShiftRow(State);
                MixColumn(State);
                AddRoundKey(State, RoundKey)}


           FinalRound(State, RoundKey)//最后一轮不做mixcolumn
              { ByteSub(State);
                 ShiftRow(State); 
                 AddRoundKey(State, RoundKey);}
    }    



    展开全文
  • AES标准 & Rijndael算法

    2019-09-25 12:13:34
    AES, Advanced Encryption Standard,其实是一套标准:FIPS 197,而我们所说的AES算法其实是Rijndael算法。 NIST (National INstitute of Standards and Technology) 在1997年9月12日公开征集更高效更安全的替代DES...
  • Rijndael算法的Flash演示

    2009-06-28 16:59:28
    一个关于Rijndael算法的演示flash,详细讲解了该算法的每一步骤,比直接看代码更容易理解该算法
  • Rijndael算法的研究,鉴权机制,注册中的鉴权,安全性
  • 本文通过深入分析Rijndael算法,改进了算法的几个有可能产生不安全隐患的步骤,首先是对于最可能被攻击的混列(MixColumns)进行的优化,使该步骤变成简单的查表而不是域乘,增加了非线形安全性;而对于子密钥的生成...
  • 在介绍新型高级加密标准(advance encryption standard, AES)-Rijndael算法的基础上,重点介绍了算法的实现及相应的解密过程;并结合算法的实现与解密过程对该算法的优点和应用前景作了简要分析。
  • Rijndael算法C源码

    千次阅读 2013-11-13 13:05:36
    Rijndael算法C源码
  • Rijndael 算法以及VC调用 和大家分享
  • C#实现AES(Rijndael算法)加密解密

    万次阅读 2017-05-16 11:20:12
    AES(Rijndael算法) Rijndael(读作rain-dahl)是由美国国家标准与技术协会(NIST)所选的高级加密标准(AES)的候选算法。 Rijndael算法首先是一个密钥分组加密的算法,通过置换(permutations )和替换...
  • Rijndael算法的JAVA实现

    2008-10-25 19:00:51
    Rijndael算法的JAVA实现,并用其构成伪随机序列
  • 高级加密标准Rijndael算法的一种改进
  • AES标准及Rijndael算法解析

    千次阅读 2018-10-17 09:28:54
    AES, Advanced Encryption Standard,其实是一套标准:FIPS 197,而我们所说的AES算法其实是Rijndael算法。 NIST (National INstitute of Standards and Technology) 在1997年9月12日公开征集更高效更安全的替代DE....
  • AES, Advanced Encryption Standard,其实是一套标准:FIPS 197,而我们所说的AES算法其实是Rijndael算法(微信小程序加密传输就是用这个加密算法的)。 NIST (National INstitute of Standards and Technology) 在...
  • 雪崩 Rijndael 算法的实现,用 128 位密钥加密/解密 128 位块并测量雪崩效应
  • 使用Rijndael算法的加密器及其源代码,使用64位密钥和初始向量。
  • 【密码学】DES算法和AES算法(Rijndael算法)数学原理及实现 背景 DES,Data Encryption Standard, 数据加密标准。 尽管DES是一个很宽泛的名字,但是它指代的只是一个具体的标准。它在1970年代被美国NBS接受为信息...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 4,788
精华内容 1,915
关键字:

rijndael算法