网站优化 济南,网站设计宁波,襄阳做网站公司有哪些,公司让做网站违法一、摘要 AES#xff08;The Advanced Encryption Standard#xff09;是美国国家标准与技术研究所用于加密电子数据的规范#xff0c;在2002年5月26日建立。它被预期能成为人们公认的加密包括金融、电信和政府数字信息的方法。AES 是一个新的可以用于保护电子数据的加密算法… 一、摘要 AESThe Advanced Encryption Standard是美国国家标准与技术研究所用于加密电子数据的规范在2002年5月26日建立。它被预期能成为人们公认的加密包括金融、电信和政府数字信息的方法。 AES 是一个新的可以用于保护电子数据的加密算法。明确地说AES 是一个迭代的、对称密钥分组的密码它可以使用128、192 和 256 位密钥并且用 128 位16字节分组加密和解密数据。与公共密钥密码使用密钥对不同对称密钥密码使用相同的密钥加密和解密数据。通过分组密码返回的加密数据 的位数与输入数据相同。迭代加密使用一个循环结构在该循环中重复置换permutations 和替换(substitutions输入数据。 二、AES算法概述 AES 算法是基于置换和代替的。置换是数据的重新排列而代替是用一个单元数据替换另一个。AES 使用了几种不同的技术来实现置换和替换。 下面是你要加密的128位值以及它们对应的索引数组 00 11 22 33 44 55 66 77 88 99 aa bb cc dd ee ff 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 192位密钥的值是 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10 11 12 13 14 15 16 17 0 1 2 3 4 5 6 7 8 9 10 1112 13 14 15 16 17 18 19 20 21 22 23 当 AES 的构造函数constructor被调用时用于加密方法的两个表被初始化。第一个表是代替盒称为S-盒。它是一个16×16的矩阵。S-盒的前五行和前五列如下图所示。 在幕后加密例程获取该密钥数组并用它来生成一个名为w[]的密钥调度表如下图所示。 w[] 最初的 Nk (6) 行被作为种子用原始密钥值0x00 到0x17。剩余行从种子密钥来产生。变量 Nk 代表以 32 位字为单位的种子密钥长度。稍后我分析 AES 实现时你将清楚地看到 w[] 是怎样产生的。 关键是这里现在有许多密钥使用而不只是一个。这些新的密钥被称为轮密钥round keys以将它们与原始种子密钥区别开来。 AES 加密例程开始是拷贝 16 字节的输入数组到一个名为 State 态的 4×4 字节矩阵中参见下图 AES 加密算法 取名为 Cipher它操作 State[]。 在规范中加密算法实现的一个预备的处理步骤被称为 AddRoundKey轮密钥加。AddRoundKey用密钥调度表中的前四行对 State 矩阵实行一个字节一个字节的异或XOR操作并用轮密钥表 w[c,r] 异或 输入 State[r,c]。 举个例子如果 State 矩阵的第一行保存的字节是{ 00, 44, 88, cc }第一列密钥调度表是{ 00, 04, 08, 0c }那么新的 State[0,2] 值是用 w[2,0]( 0x08 或 0x80 )异或 State[0,2](0x88)的结果 1 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 XOR 1 0 0 0 0 0 0 0 AES 算法的主循环对 State 矩阵执行四个不同的操作在规范中被称为 SubBytes字节替换、ShiftRows行位移变换、MixColumns列混合变换 和 AddRoundKey。除了每次循环 AddRoundKey 都被调用并使用密钥调度表的下面四行外AddRoundKey 与预备处理步骤中的 AddRoundKey 相同。SubBytes 例程是一个代替操作它将 State 矩阵中的每个字节替换成一个由 Sbox 决定的新字节。比如如果 State[0,1]的值是 0x40 如果你想找到它的代替者你取 State[0,1] 的值 (0x40) 并让 x 等于左边的数字(4)并让 y 等于右边的数字(0)。然后你用 x 和 y 作为索引 进到 Sbox 表中寻找代替值。 ShiftRows 是一个置换操作它将 State 矩阵中的字节向左旋转。下图示范了 ShiftRows 如何操作 State[]。State 的第0行被向左旋转0个位置State 的第1行被向左旋转1个位置State 的第2行被向左旋转2个位置而 State 的第3行被向左旋转3个 位置。 MixColumns 是一个代替操作它是理解 AES 算法时最具技巧或者说是最需要动脑筋的部分的部分。它用 State 字节列的值进行数学域加和域乘的结果代替每个字节。我将在下一节中 详细解释专门的域加和域乘细节。 假设 State[0,1] 的值是0x09并且列1上的其它值分别为 0x600xe1 和 0x04那么State[0,1]的新值计算如下 State[0,1] (State[0,1] * 0x01) (State[1,1] * 0x02) (State[2,1] * 0x03) (State[3,1] * 0x01) (0x09 * 0x01) (0x60 * 0x02) (0xe1 * 0x03) (0x04 * 0x01) 0x57 此处加法和乘法是专门的数学域操作而不是平常整数的加法和乘法。 SubBytes、ShiftRows、MixColumns 和 AddRoundKey 四个操作在一个执行 Nr 次的循环里被调用Nr 为给定密钥大小的轮数减 1。加密算法使用的轮数要么是1012要么是14这依赖于种子密钥长度是128位、192 位还是 256 位。在这个例子中因为 Nr 等于12 则这四个操作被调用11次。该迭代完成后在拷贝 State 矩阵到输出参数前加密算法调用 SubBytes、ShiftRows 和 AddRoundKey 后结束。 大致说来AES 加密算法的核心有四个操作。AddRoundKey 使用从种子密钥值中生成的轮密钥代替 4 组字节。SubBytes 替换用一个代替表 替换单个字节。ShiftRows 通过旋转 4字节行 的 4 组字节进行序列置换。MixColumns 用域加和域乘的组合来替换字节。 三、有限域GF(28)的加法和乘法 正如你所看到的AES 加密算法使用相当简单明了的技术来代替和置换除 MixColumns 例程以外。MixColumns 使用特殊的加法和乘法。AES 所用的加法和乘法是基于数学译者注近世代数的域论。尤其是 AES 基于有限域GF(28)。 GF(28)由一组从 0x00 到 0xff 的256个值组成加上加法和乘法因此是(28)。GF代表伽罗瓦域以发明这一理论的数学家的名字命名。GF(28) 的一个特性是一个加法或乘法的操作的结果必须是在{0x00 ... 0xff}这组数中。虽然域论是相当深奥的但GF(28)加法的最终结果却很简单。GF(28) 加法就是异或XOR操作。 然而GF(28)的乘法有点繁难。正如你稍后将在 C# 实现中所看到的AES的加密和解密例程需要知道怎样只用七个常量 0x01、0x02、0x03、0x09、0x0b、0x0d 和 0x0e 来相乘。所以我不全面介绍GF(28)的乘法而只是针对这七种特殊情况进行说明。 在GF(28)中用0x01的乘法是特殊的它相当于普通算术中用1做乘法并且结果也同样—任何值乘0x01等于其自身。 现在让我们看看用0x02做乘法。和加法的情况相同理论是深奥的但最终结果十分简单。只要被乘的值小于0x80这时乘法的结果就是该值左移1比特位。如果被乘的值大于或等于0x80这时乘法的结果就是左移1比特位再用值0x1b异或。它防止了“域溢出”并保持乘法的乘积在范围以内。 一旦你在GF(28)中用0x02建立了加法和乘法你就可以用任何常量去定义乘法。用0x03做乘法时你可以将 0x03 分解为2的幂之和。为了用 0x03 乘以任意字节b 因为 0x03 0x02 0x01因此 b * 0x03 b * (0x02 0x01) (b * 0x02) (b * 0x01) 这是可以行得通的因为你知道如何用 0x02 和 0x01 相乘和相加同哩用0x0d去乘以任意字节b可以这样做 b * 0x0d b * (0x08 0x04 0x01) (b * 0x08) (b * 0x04) (b * 0x01) (b * 0x02 * 0x02 * 0x02) (b * 0x02 * 0x02) (b * 0x01) 在加解密算法中AES MixColumns 例程的其它乘法遵循大体相同的模式如下所示 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) 总之在GF(28)中加法是异或操作。其乘法将分解成加法和用0x02做的乘法而用0x02做的乘法是一个有条件的左移1比特位。AES规范中包括大量 有关GF(28)操作的附加信息。 四、密钥扩展 AES加密和解密算法使用了一个由种子密钥字节数组生成的密钥调度表。AES规范中称之为密钥扩展例程KeyExpansion。从本质上讲从一个原始密钥中生成多重密钥以代替使用单个密钥大大增加了比特位的扩散。虽然不是无法抵御的困难但理解 KeyExpansion 仍是 AES 算法中的一个难点。 KeyExpansion 例程高级伪代码如下所示 KeyExpansion(byte[] key, byte[][4] w) { copy the seed key into the first rows of w for each remaining row of w { use two of the previous rows to create a new row } } 用前面两行来产生一个新行use two of the previous rows to create a new row的例程用到了两个子 例程RotWord 和 SubWord 以及一个名为“Rcon”的常数表作为“轮常数”。让我们先来逐个看一下这三东西然后再回到整个 KeyExpansion 的讨论中来。 RotWord 例程很简单。它接受一个4个字节的数组并将它们向左旋转一个位置。因为轮调度表 w[] 有四列RotWord 将 w[]的1行左旋。注意 KeyExpansion 使用的这个 RotWord 函数与加密算法使用的 ShiftRows 行位移变换例程非常相似只是它 处理的是单行密钥调度 w[]而不是整个加密状态表 State[]。 SubWord 例程使用替换表 Sbox 对一给定的一行密钥调度表 w[] 进行逐字节替换。KeyExpansion 操作中的替换实际上就像在加密算法中的 替换一样。被代替的输入字节被分成 (x,y) 对它被当作进入替换表 Sbox 的索引。举例来说0x27的代替结果是 x2 和 y7并且 Sbox[2,7] 返回 0xcc。 KeyExpansion 例程使用一个被称为轮常数表的数组 Rcon[]。这些常数都是4个字节每一个与密钥调度表的某一行相匹配。AES 的 KeyExpansion 例程需要11个轮常数。你可以在 Figure 7 中看到这些常数清单。 每个轮常数的最左边的字节是GF(28)域中2的幂次方。它的另一个表示方法是其每个值是前一个值乘上0x02正如前一部分讨论 GF(28) 乘法 时所描述的那样。注意 0x80 × 0x02 0x1b 是 0x80 左移1个比特位后紧接着与 0x1b 进行异或如前所述。 现在让我们更进一步看看 KeyExpansion 内幕中的循环。这里所用的伪码比以前更为详细这个循环是 for (row Nk; row (4 * Nr1); row) { temp w[row-1] if (row % Nk 0) { temp SubWord(RotWord(temp)) xor Rcon[row/Nk] } else if (Nk 8 and row % Nk 4) { temp SubWord(temp) w[row] w[row-Nk] xor temp } } 先不要去看if子句你将看到密钥调度表 w[] 的每一行都是前面一行与行 Nk 异或的结果4, 6, 或 8 取决于密钥的长度。if条件的第一部分用 SubWord、RotWord 以及与轮常数的异或修改密钥调度表的每个第4、第6或第8行取决于是否密钥的长度是128、192或256位。这个条件的第二部分将修改行 12、20 和 28 等等。对于256位密钥而言每 一个第8行都将添加密钥调度额外的可变性。 让我们用本文开头所举的例子来考察 KeyExpansion 是如何开始的。种子密钥是192-bit / 6-word 值 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10 11 12 13 14 15 16 17 密钥调度字节表 w[] 的维数是 4 列并且 Nb × (Nr 1) 等于 4 × (12 1)或 52 行。KeyExpansion 将种子密钥的值拷贝到密钥调度字节表 w[] 的第一行。因为我的种子密钥是 192 位24字节并且 w[] 表总是 4 列在这种情况下KeyExapansion 将种子密钥拷贝到 w[] 的前面 6 行。现在让我们看看 KeyExapansion 例程是如何填充密钥调度表其余部分的。在我的例子里第一个被计算的行是第 6 行 因为第0-5行已被种子密钥的值填上了 temp w[row-1] 14 15 16 17 条件 (row % Nk 0)为真因此首先 RotWord 子程序被应用 temp 15 16 17 14 这时 SubWord 被应用 temp 59 47 f0 fa 用 Rcon[row / Nk] Rcon[6 / 6] 01 00 00 00 进行异或 temp 58 47 f0 fa 这时用 w[row-Nk] w[6-6] 00 01 02 03 异或产生了下面结果 w[6] 58 46 f2 f9 密钥调度表 w[] 中其余所有行来重复这个过程本身。 总而言之AES 加密和解密的一个重要部分就是从最初的种子密钥中生成多重轮密钥。这个 KeyExapansion 算法生成一个密钥调度并 以某种方式进行替代和置换在这种方式中加密和解密算法极其相似。 转自http://www.cnblogs.com/txw1958/p/aes.html