【正文】
ation 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, symmetrickey 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 publickey ciphers, which use a pair of keys, symmetrickey 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 16byte block of data using a 192bit 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 bination of advances in hardware, software, and cryptanalysis theory allowed a DESencrypted message to be decrypted in 56 hours. Since that time numerous other successful attacks on DESencrypted 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 bee the de facto standard for encrypting all forms of electronic data including data used in mercial applications such as banking and financial transactions, telemunications, 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, let39。 在任何軟件設(shè)計(jì)過(guò)程中安全已不再是后顧之憂(yōu)。 以 .NET Framework 庫(kù)的形式從 Microsoft 以及第三方供應(yīng)商處獲得對(duì) AES 的廣泛支持只是一個(gè)時(shí)間問(wèn)題。AES 加密的數(shù)據(jù)在某種意義上是牢不可破的,因?yàn)闆](méi)有已知的密碼分析攻擊可以解密 AES 密文,除非強(qiáng)行遍歷搜索所有可能的 256 位密鑰。 針對(duì)這種攻擊的兩個(gè)安全 措施是加入虛指令,以便所以所有乘法都需要相同數(shù)量的指令,或者將域乘實(shí)現(xiàn)為一個(gè)查詢(xún)表,就象我前面描述的那樣。 注意針對(duì) AES 密碼最可能成功的攻擊來(lái)自一個(gè)允許時(shí)間選擇攻擊的弱實(shí)現(xiàn)。 AES 的安全性怎樣呢?這是一個(gè)很難回答的問(wèn)題,但是一般多數(shù)人的意見(jiàn)是:它是目前可獲得的最安全的加密算法。例如,所給出 的構(gòu)造函數(shù)甚至都不檢查種子密鑰參數(shù)的長(zhǎng)度。此外,實(shí)現(xiàn) GF(28) 乘法另一途徑是通過(guò)在兩個(gè) 256 個(gè)字節(jié)的數(shù)組里查找,通常稱(chēng)為 alog[] 和 log[],因?yàn)樗鼈冊(cè)? GF(28)中基于某些類(lèi)似對(duì)數(shù)的方法。 可選實(shí)現(xiàn)另外一個(gè)有趣的可能性是 Cipher 和 InvCipher 方法所用的 GF(28) 乘法。事實(shí)上, AES 的每個(gè)例程都能針對(duì)非常昂貴的內(nèi)存資源進(jìn)行性能優(yōu)化,反之亦然。 實(shí)現(xiàn)選擇 現(xiàn)在讓我們看看本文 AES 實(shí)現(xiàn)中出現(xiàn)的 一些重要的變量,本文提供的代碼可能出現(xiàn)的擴(kuò)展,以及針對(duì) AES 的密碼分析學(xué)攻擊。這個(gè) demo 程序用一個(gè) “空密鑰 ”( null key)作為種子密鑰,通過(guò)為構(gòu)造函數(shù)提供一個(gè)啞參數(shù) new byte[16] 使得它全部由零字節(jié)組成。我創(chuàng)建了一個(gè)基于 Windows 的小 Demo 程序,它接受一個(gè) 單純的字符串 ——有 8 個(gè)字符 (16byte) ,對(duì)它進(jìn)行加密和解密處理??纯? Figure 15,它是我用來(lái)生成輸出 Figure 1 的代碼。并且 4 等于 2 的平方, 8 等于 2 的立方,你可以將 14 表示為 2 + 22 + 23。 InvMixColumns 方法還原 MixColumns 的工作,但沒(méi)有用顯而易見(jiàn)的方法。 正如你可能猜測(cè)到的, iSbox[] 就是還原任何被 Sbox[] 處理的對(duì)應(yīng)操作。其次, InvCipher 調(diào)用的是一個(gè) AddRoundKey 方法而不是 InvAddRoundKey 方法。 AES 規(guī)范稱(chēng)解密例程為 InvCipher,而不是 Decipher 或 Decrypt 中的一個(gè)。 SubBytes 用某個(gè)替換表中的值替代字節(jié)。 正如我前面討論的,被 0x02 乘是所有 GF(28) 乘法的基本操作。 乘法所用的常量系數(shù)基于域論的,并且是 0x01, 0x02或 0x03中的任意一個(gè)值?;叵胍幌拢?ShiftRows(可能叫做 RotateRows 更好)將 row[0] 向左旋轉(zhuǎn) 0 個(gè)位置,將 row[1] 向左旋轉(zhuǎn) 1 位置等等。AddRoundKey 方法需要知道它處在那一輪,以便它正確引用 4行密鑰調(diào)度數(shù)組 w[]。 Cipher 方法以拷貝明文輸入數(shù)組到狀態(tài)矩陣 State[] 為開(kāi)始。構(gòu)造函數(shù)為輸入塊長(zhǎng)度,種子密鑰長(zhǎng)度 以及加密算法的輪數(shù)賦值,并將種子密鑰拷貝到一個(gè)名為 key 的數(shù)據(jù)成員中。 result[0] = substitute。雖然有些長(zhǎng),但比實(shí)際代碼更可讀,我可以象下面這樣: int x = word[0] 4。 SubWord 和 RotWord 的代碼是相當(dāng)簡(jiǎn)單,參見(jiàn)本文附帶的 AesLib 源代碼,它應(yīng)該很容易理解。它需要一些 從 byte 到 int 的強(qiáng)制類(lèi)型轉(zhuǎn)換并轉(zhuǎn)回到 byte,因?yàn)楫惢虿僮?“^”是不能定義在 C 的 byte 類(lèi)型上,例如: temp[0] = (byte)( (int)temp[0] ^ (int)[row/Nk,0] )。 [row,1] = [4*row+1]。規(guī)范文檔使用一個(gè)假設(shè)的 4字節(jié)的字?jǐn)?shù)據(jù)類(lèi)型。置換輪常數(shù)表 Rcon 的賦值代碼參見(jiàn) Figure 7。填充 iSbox[] 代碼 類(lèi)似。 (, 0)。 } 該構(gòu)造函數(shù)首先調(diào)用一個(gè)輔助方法 SetNbNkNr 給 Nb、 Nk 和 Nr 賦值,如 Figure 8 所示。 BuildSbox()。 我選擇少許笨拙的方法 來(lái)命名 Cipher 和 InvCipher,因?yàn)樗鼈兪怯迷? AES 規(guī)范文檔中的。 當(dāng)設(shè)計(jì)一個(gè)類(lèi)接口時(shí),我喜歡向后來(lái)做。密鑰長(zhǎng)度 依照枚舉參數(shù) KeySize 的值被賦值為 6 或 8。 該規(guī)范文檔一般用字節(jié)作為基本儲(chǔ)存單元而不是用 4字節(jié)的字作為兩個(gè)重要數(shù)據(jù)成員的長(zhǎng)度。 private byte[,] w。 private int Nr。(即便它們是那么晦澀,如 “Nr”和 “W”)。 用 C 編寫(xiě) AES 類(lèi)構(gòu)造函數(shù) 現(xiàn)在我已研究了構(gòu)成 AES 加密算法 的各個(gè)成分,我將用 C 來(lái)實(shí)現(xiàn)它?,F(xiàn)在讓我們看看 KeyExapansion 例程是如何填充密鑰調(diào)度表其余部分的。 讓我們用本文開(kāi)頭所舉的例子來(lái)考察 KeyExpansion 是如何開(kāi)始的。 row (4 * Nr+1)。它的另一個(gè)表示方法是其每個(gè)值是前一個(gè)值乘上 0x02,正如前一部分討論 GF(28) 乘法 時(shí)所描述的那樣。這些常數(shù)都是4 個(gè)字節(jié),每一個(gè)與密鑰調(diào)度表的某一行相匹配。 KeyExpansion 操作中的替換實(shí)際上就像在加密算法中的 替換一樣。它接受一個(gè) 4 個(gè)字節(jié)的數(shù)組并將它們向左旋轉(zhuǎn)一個(gè)位 置。雖然不是無(wú)法抵御的困難,但理解 KeyExpansion 仍是 AES 算法中的一個(gè)難點(diǎn)。 AES 規(guī)范中包括大量 有關(guān) GF(28)操作的附加信息。 一旦你在 GF(28)中用 0x02建立了加法和乘法,你就可以用任何常量去定義乘法。和加法的情況相同,理論是深?yuàn)W的,但最終結(jié)果十分簡(jiǎn)單。正如你稍后將在 C 實(shí)現(xiàn)中所看到的, AES的加密和解密例程需要知道怎樣只用七個(gè)常量 0x0 0x0 0x0 0x0 0x0b、0x0d 和 0x0e 來(lái)相乘。 GF(28) 的一個(gè)特性是一個(gè)加法或乘法的操作的結(jié)果必須是在 {0x00 ... 0xff}這組數(shù)中。 AES 所用的加法和乘法是基于數(shù)學(xué)(譯者注:近世代數(shù))的域論。 ShiftRows 通過(guò)旋轉(zhuǎn) 4字節(jié)行 的 4 組字節(jié)進(jìn)行序列置換。該迭代完成后,在拷貝 State 矩陣到輸出參數(shù)前,加密算法調(diào)用 SubBytes、 ShiftRows 和 AddRoundKey 后結(jié)束。 假設(shè) State[0,1] 的值是 0x09,并且列 1上的其它值分別為 0x60, 0xe1 和 0x04,那么 State[0,1]的新值計(jì)算如下: 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 此處加法和乘法是專(zhuān)門(mén)的數(shù)學(xué)域操作,而不是平常整數(shù)的加法和乘法。 State 的第 0行被向左旋轉(zhuǎn) 0個(gè)位置, State 的第 1行被向左旋轉(zhuǎn) 1個(gè)位置, State 的第 2行被向左旋轉(zhuǎn) 2個(gè)位置,而 State 的第 3行被向左旋轉(zhuǎn) 3個(gè) 位置。比如,如果 State[0,1]的值是 0x40 如果你想找到它的代替者,你取 State[0,1] 的值 (0x40) 并讓 x 等于左邊的數(shù)字 (4)并讓 y 等于右邊的數(shù)字 (0)。 AddRoundKey 用密鑰調(diào)度表中的前四行對(duì) State 矩陣實(shí)行一個(gè)字節(jié)一個(gè)字節(jié)的異或( XOR)操作,并用輪密鑰表 w[c,r] 異或 輸入 State[r,c]。 Figure 4 State (態(tài))數(shù)組 AES 加密例程開(kāi)始是拷貝 16 字節(jié)的輸入數(shù)組到一個(gè)名為 State (態(tài))的 44 字節(jié)矩陣中。變量 Nk 代表以 32 位字為單位的種子密鑰長(zhǎng)度。 S盒的前五行和前五列如 Figure 2 所示。為了闡明這