用新的高级加密标准(AES)保持你的数据安全 毕业论文外文翻译
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
Keep Your Data Secure with the New Advanced Encryption
Standard
James McCaffrey
SUMMARY
The Advanced Encryption Standard (AES) is a National Institute of Standards and Technology specification for the encryption of electronic data. It is expected to become the accepted means of encrypting digital information, including financial, telecommunications, and government data. This article presents an overview of AES and explains the algorithms it uses..After reading this article you will be able to encrypt data using AES, test AES-based software, and use AES encryption in your systems.
Note that the code presented in this article and any other implementation based on this article is subject to applicable Federal cryptographic module export controls (see Commercial Encryption Export Controls for the exact regulations).
AES is a new cryptographic algorithm that can be used to protect electronic data. Specifically, AES is an iterative, symmetric-key block cipher that can use keys of 128, 192, and 256 bits, and encrypts and decrypts data in blocks of 128 bits (16 bytes). Unlike public-key ciphers, which use a pair of keys, symmetric-key ciphers use the same key to encrypt and decrypt data. Encrypted data returned by block ciphers have the same number of bits that the input data had. Iterative ciphers use a loop structure that repeatedly performs permutations and substitutions of the input data. Figure 1 shows AES in action encrypting and then decrypting a 16-byte block of data using a
192-bit key.
Figure 1 Some Data
AES is the successor to the older Data Encryption Standard (DES). DES was approved as a Federal standard in 1977 and remained viable until 1998 when a combination of advances in hardware, software, and cryptanalysis theory allowed a DES-encrypted message to be decrypted in 56 hours. Since that time numerous other successful attacks on DES-encrypted data have been made and DES is now
considered past its useful lifetime.
In late 1999, the Rijndael (pronounced "rain doll") algorithm, created by researchers Joan Daemen and Vincent Rijmen, was selected by the NIST as the proposal that best met the design criteria of security, implementation efficiency, versatility, and simplicity. Although the terms AES and Rijndael are sometimes used interchangeably, they are distinct. AES is widely expected to become the de facto standard for encrypting all forms of electronic data including data used in commercial applications such as banking and financial transactions, telecommunications, and private and Federal information.
Overview of the AES Algorithm
The AES algorithm is based on permutations and substitutions. Permutations are rearrangements of data, and substitutions replace one unit of data with another. AES performs permutations and substitutions using several different techniques. To illustrate these techniques, let's walk through a concrete example of AES encryption using the data shown in Figure 1.
The following is the 128-bit value that you will encrypt with the indexes array: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
The 192-bit key value is:
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 11 12 13 14 15 16 17 18 19 20 21 22 23
Figure 2 Sbox
When the AES constructor is called, two tables that will be used by the encryption method are initialized. The first table is a substitution box named Sbox. It is a 16 × 16 matrix. The first five rows and columns of Sbox are shown in Figure 2. Behind the scenes, the encryption routine takes the key array and uses it to generate a "key schedule" table named w[], shown in Figure 3.
Figure 3 Key Sched.
The first Nk (6) rows of w[] are seeded with the original key value (0x00 through 0x17) and the remaining rows are generated from the seed key. The variable Nk
represents the size of the seed key in 32-bit words. You'll see exactly how w[] is generated later when I examine the AES implementation. The point is that there are now many keys to use instead of just one. These new keys are called the round keys to distinguish them from the original seed key.
Figure 4 State
The AES encryption routine begins by copying the 16-byte input array into a 4×4 byte matrix named State (see Figure 4). The AES encryption algorithm is named Cipher and operates on State[] and can be described in pseudocode (see Figure 5).
The encryption algorithm performs a preliminary processing step that's called AddRoundKey in the specification. AddRoundKey performs a byte-by-byte XOR operation on the State matrix using the first four rows of the key schedule, and XORs input State[r,c] with round keys table w[c,r].
For example, if the first row of the State matrix holds the bytes { 00, 44, 88, cc }, and the first column of the key schedule is { 00, 04, 08, 0c }, then the new value of State[0,2] is the result of XORing State[0,2] (0x88) with w[2,0] (0x08), or 0x80:
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
The main loop of the AES encryption algorithm performs four different operations on the State matrix, called SubBytes, ShiftRows, MixColumns, and AddRoundKey in the specification. The AddRoundKey operation is the same as the preliminary AddRoundKey except that each time AddRoundKey is called, the next four rows of the key schedule are used. The SubBytes routine is a substitution operation that takes each byte in the State matrix and substitutes a new byte determined by the Sbox table. For example, if the value of State[0,1] is 0x40 and you want to find its substitute, you take the value at State[0,1] (0x40) and let x equal the left digit (4) and y equal the right digit (0). Then you use x and y as indexes into the Sbox table to find the substitution value, as shown in Figure 2.
ShiftRows is a permutation operation that rotates bytes in the State matrix to the left. Figure 6 shows how ShiftRows works on State[]. Row 0 of State is rotated 0 positions to the left, row 1 is rotated 1 position left, row 2 is rotated 2 positions left, and row 3 is rotated 3 positions left.
Figure 6 Running ShiftRows on State
The MixColumns operation is a substitution operation that is the trickiest part of the AES algorithm to understand. It replaces each byte with the result of mathematical field additions and multiplications of values in the byte's column. I will explain the details of special field addition and multiplication in the next section.
Suppose the value at State[0,1] is 0x09, and the other values in column 1 are 0x60, 0xe1, and 0x04; then the new value for State[0,1] is shown in the following:
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
The addition and multiplication are special mathematical field operations, not the usual addition and multiplication on integers.
The four operations SubBytes, ShiftRows, MixColumns, and AddRoundKey are called inside a loop that executes Nr times—the number of rounds for a given key size, less 1. The number of rounds that the encryption algorithm uses is either 10, 12, or 14 and depends on whether the seed key size is 128, 192, or 256 bits. In this example, because Nr equals 12, the four operations are called 11 times. After this iteration completes, the encryption algorithm finishes by calling SubBytes, ShiftRows, and AddRoundKey before copying the State matrix to the output parameter.
In summary, there are four operations that are at the heart of the AES encryption algorithm. AddRoundKey substitutes groups of 4 bytes using round keys generated from the seed key value. SubBytes substitutes individual bytes using a substitution table. ShiftRows permutes groups of 4 bytes by rotating 4-byte rows. MixColumns substitutes bytes using a combination of both field addition and multiplication.
Field Addition and Multiplication in GF(28)
As you've seen, the AES encryption algorithm uses fairly straightforward techniques for substitution and permutation, except for the MixColumns routine. The MixColumns routine uses special addition and multiplication. The addition and multiplication used by AES are based on mathematical field theory. In particular, AES is based on a field called GF(28).
The GF(28) field consists of a set of 256 values from 0x00 to 0xff, plus addition and multiplication, hence the (28). GF stands for Galois Field, named after the mathematician who founded field theory. One of the characteristics of GF(28) is that the result of an addition or multiplication operation must be in the set {0x00 ... 0xff}. Although the theory of fields is rather deep, the net result for GF(28) addition is simple: GF(28) addition is just the XOR operation.
Multiplication in GF(28) is trickier, however. As you'll see later in the C# implementation, the AES encryption and decryption routines need to know how to multiply by only the seven constants 0x01, 0x02, 0x03, 0x09, 0x0b, 0x0d, and 0x0e. So instead of explaining GF(28) multiplication theory in general, I will explain it just for these seven specific cases.
Multiplication by 0x01 in GF(28) is special; it corresponds to multiplication by 1 in normal arithmetic and works the same way—any value times 0x01 equals itself.
Now let's look at multiplication by 0x02. As in the case of addition, the theory is deep, but the net result is fairly simple. If the value being multiplied is less than 0x80, then the result of multiplication is just the value left-shifted 1 bit position. If the value being multiplied is greater than or equal to 0x80, then the result of multiplication is the value left-shifted 1 bit position XORed with the value 0x1b. This prevents "field overflow" and keeps the product of the multiplication in range.
Once you've established addition and multiplication by 0x02 in GF(28), you can use them to define multiplication by any constant. To multiply by 0x03 in GF(28), you can decompose 0x03 as powers of 2 and additions. To multiply an arbitrary byte b by
0x03, observe that 0x03 = 0x02 + 0x01. Thus:
b * 0x03 = b * (0x02 + 0x01)
= (b * 0x02) + (b * 0x01)
This can be done because you know how to multiply by 0x02 and 0x01 and how to perform addition. Similarly, to multiply an arbitrary byte b by 0x0d, you do this:
b * 0x0d = b * (0x08 + 0x04 + 0x01)
= (b * 0x08) + (b * 0x04) + (b * 0x01)
= (b * 0x02 * 0x02 * 0x02) + (b * 0x02 * 0x02) + (b * 0x01)
The other multiplications needed for the AES MixColumns routine in the encryption and decryption algorithm follow the same general pattern, as shown here:
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)
To summarize, addition in GF(28) is the XOR operation. Multiplication in GF(28) reduces to additions and multiplications by 0x02, where multiplication by 0x02 is a conditional 1-bit left shift. The AES specification contains a lot of additional information about operations in GF(28).
Key Expansion
The AES encryption and decryption algorithms use a key schedule generated from the seed key array of bytes. The AES specification refers to this as the KeyExpansion routine. Generating, in essence, multiple keys from an initial key instead of using a single key greatly increases the diffusion of bits. Although not overwhelmingly difficult, understanding KeyExpansion is one of the trickier parts of the AES algorithm. In high-level pseudocode, the KeyExpansion routine looks like the following:
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
}
}
The "use two of the previous rows to create a new row" routine makes use of two subroutines, RotWord and SubWord, and a table of constants named Rcon (for "round constants"). Let's look at each of these three items and then come back to the KeyExpansion routine as a whole.
The RotWord routine is simple. It accepts an array of 4 bytes and rotates them 1
position left. Because the round schedule table w[] has four columns, RotWord rotates a row of w[] to the left. Notice that the RotWord function used by KeyExpansion is very similar to the ShiftRows routine used by the encryption algorithm except that it works on a single row of the key schedule w[] instead of the entire encryption state table State[].
The SubWord routine performs a byte-by-byte substitution on a given row of the key schedule table w[] using the substitution table Sbox. The substitutions in KeyExpansion operate exactly like those in the encryption algorithm. The input byte to be substituted is separated into an (x,y) pair which are used as indexes into the substitution table Sbox. For example, substitution for 0x27 results in x = 2 and y = 7, and Sbox[2,7] returns 0xcc.
The KeyExpansion routine uses an array Rcon[], called the round constant table. These constants are 4 bytes each to match with a row of the key schedule table. The AES KeyExpansion routine requires 11 round constants. You can see these constants listed in Figure 7.
Figure 7 Initializing Rcon
The leftmost byte of each round constant is a power of 2 in the GF(28) field. Another way of looking at it is to observe that each value is the previous value times 0x02, as described in the previous section discussing multiplication in GF(28). Notice that 0x80 ×0x02 = 0x1b is 0x80 left-shifted 1 bit followed by an XOR with 0x1b, as described earlier.
Now let's take a closer look at the loop inside KeyExpansion. In more detailed pseudocode than before, the loop is:
for (row = Nk; row < (4 * Nr+1); ++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
}
Ignoring the if clause for a moment, you'll see that each row of the key schedule table w[] is the result of XORing the previous row with the row Nk (4, 6, or 8 depending on the key size) rows before. The first part of the if conditional modifies every fourth, sixth, or eighth row of the key schedule with SubWord, RotWord, and XORing with a round constant, depending on whether the key size is 128, 192, or 256 bits. The second part of the conditional will modify rows 12, 20, 28 and so on—every eighth row—for a 256-bit key to add additional variability to the key schedule.
Let's see how KeyExpansion gets started with the example presented at the beginning of this article. The seed key is the 192-bit / 6-word value:
00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10 11 12 13 14 15 16 17
The key schedule byte table w[] has the dimensions 4 columns and Nb ×(Nr + 1) equals 4 × (12 + 1), or 52 rows. The KeyExpansion routine copies the values in the seed key into the first rows of the key schedule byte table w[]. Because my seed key is 192 bits (24 bytes), and the w[] table always has 4 columns, in this case KeyExapansion copies the seed key into the first 6 rows of w[]. Now let's see how the KeyExpansion routine fills the rest of the key schedule table. In my example, the first calculated row is row 6 because rows 0 to 5 were filled with the seed key values: temp = w[row-1] = 14 15 16 17
The condition (row % Nk == 0) is true, so first the RotWord subroutine is applied: temp = 15 16 17 14
Then SubWord is applied:
temp = 59 47 f0 fa
Then XORed with Rcon[row / Nk] = Rcon[6 / 6] = 01 00 00 00:
temp = 58 47 f0 fa
This is then XORed with w[row-Nk] = w[6-6] = 00 01 02 03, yielding the following result:
w[6] = 58 46 f2 f9
The process repeats itself for all of the remaining rows in key schedule table w[].
To summarize, an important part of AES encryption and decryption is the generation of multiple round keys from the initial seed key. This KeyExpansion algorithm generates a key schedule and uses substitution and permutation in a way that is similar in most respects to the encryption and decryption algorithms.
Conclusion
The new AES will certainly become the de facto standard for encrypting all forms of electronic information, replacing DES. AES-encrypted data is unbreakable in the sense that no known cryptanalysis attack can decrypt the AES cipher text without using a brute-force search through all possible 256-bit keys.
AES is an important advance and using and understanding it will greatly increase the reliability and safety of your software systems.
用新的高级加密标准(AES)保持你的数据安全
James McCaffrey 摘要
AES(The Advanced Encryption Standard)是美国国家标准与技术研究所用于加密电子数据的规范。
它被预期能成为人们公认的加密包括金融、电信和政府数字信息的方法。
本文展示了AES的概貌并解析了它使用的算法。
在读完本文后你将能用AES加密、测试基于AES的软件并能在你的系统中使用AES加密。
AES 是一个新的可以用于保护电子数据的加密算法。
明确地说,AES 是一个迭代的、对称密钥分组的密码,它可以使用128、192 和256 位密钥,并且用128 位(16字节)分组加密和解密数据。
与公共密钥密码使用密钥对不同,对称密钥密码使用相同的密钥加密和解密数据。
通过分组密码返回的加密数据的位数与输入数据相同。
迭代加密使用一个循环结构,在该循环中重复置换(permutations )和替换(substitutions)输入数据。
Figure 1 显示了AES 用192位密钥对一个16位字节数据块进行加密和解密的情形。
AES算法概述
AES 算法是基于置换和代替的。
置换是数据的重新排列,而代替是用一个单元数据替换另一个。
AES 使用了几种不同的技术来实现置换和替换。
为了阐明这些技术,让我们用Figure 1 所示的数据讨论一个具体的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
Figure 2 S-盒(Sbox )
当AES 的构造函数(constructor)被调用时,用于加密方法的两个表被初始化。
第一个表是代替盒称为S-盒。
它是一个16×16的矩阵。
S-盒的前五行和前五列如Figure 2 所示。
在幕后,加密例程获取该密钥数组并用它来生成一个名为w[]的密钥调度表,Figure 3 所示。
Figure 3 密钥调度表(Key Sched)
w[] 最初的Nk (6) 行被作为种子,用原始密钥值(0x00 到0x17)。
剩余行从种子密钥来产生。
变量Nk 代表以32 位字为单位的种子密钥长度。
稍后我分析AES 实现时你将清楚地看到w[] 是怎样产生的。
关键是这里现在有许多密钥使用而不只是一个。
这些新的密钥被称为轮密钥(round keys)以将它们与原始种子密钥区别开来。
Figure 4 State (态)数组
AES 加密例程开始是拷贝16 字节的输入数组到一个名为State (态)的
4×4 字节矩阵中。
(参见Figure 4)。
AES 加密算法取名为Cipher,它操作State[],其过程描述的伪代码参见Figure 5 。
在规范中,加密算法实现的一个预备的处理步骤被称为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 表中寻找代替值,如Figure 2 所示。
ShiftRows 是一个置换操作,它将State 矩阵中的字节向左旋转。
Figure 6 示范了ShiftRows 如何操作State[]。
State 的第0行被向左旋转0个位置,State 的第1行被向左旋转1个位置,State 的第2行被向左旋转2个位置,而State 的第3行被向左旋转3个位置。
Figure 6 对State 进行ShiftRows 操作
MixColumns 是一个代替操作,它是理解AES 算法时最具技巧(或者说是最需要动脑筋的部分)的部分。
它用State 字节列的值进行数学域加和域乘的结果代替每个字节。
我将在下一节中详细解释专门的域加和域乘细节。
假设State[0,1] 的值是0x09,并且列1上的其它值分别为0x60,0xe1 和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。
加密算法使用的轮数要么是10,12,要么是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的代替结果是x=2 和y=7,并且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 * Nr+1); ++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 算法生成一个密钥调度并以某种方式进行替代和置换,在这种方式中,加密和解密算法极其相似。
结束语
新的AES 将无疑成为加密所有形式电子信息的事实上的标准,取代DES。
AES 加密的数据在某种意义上是牢不可破的,因为没有已知的密码分析攻击可以解密AES 密文,除非强行遍历搜索所有可能的256 位密钥。
AES 是一个重大进步,使用并理解它将大大增加软件系统的可靠性和安全性。