密鑰擴展
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 算法生成一個密鑰調度並 以某種方式進行替代和置換,在這種方式中,加密和解密算法極其相似。