AES是一個對稱密碼,旨在取代DES成為廣泛使用的標准。
一、AES的加密過程
二、AES的數據結構
加密解密算法的輸入是一個128位分組。這些分組被描述成4×4的字節方陣,這個分組被復制到state數組中,並在加密和解密的每一階段都被修改。在字節方陣中,每一格都是一個字,包含了4字節。在矩陣中字是按列排序的。
加密由N輪構成,輪數依賴於密鑰長度:16字節密鑰對應10輪,24字節密鑰對應12輪,32字節對應14輪。
三、加密解密的詳細結構
AES未使用Feistel結構。其前N-1輪由4個不同的變換組成:字節代替、行移位、列混淆和輪密鑰加。最后一輪僅包含三個變換。而在第一輪前面有一個起始的單變換(輪密鑰加),可以視為0輪。
字節代替(SubBytes):用一個S盒完成分組的字節到字節的代替。
行移位(ShiftRows):一個簡單的置換。
列混淆(MixColumns):利用域GF(28)上的算術特性的一個代替。
輪密鑰加(AddRoundKey):當前分組和擴展密鑰的一部分進行按位異或XOR。
首尾使用輪密鑰加的理由:若將其他不需要密鑰的階段放在首尾,在不知道密鑰的情況下就能計算其逆,這就不能增加算法的安全性。
加密原理:輪密鑰加實際是一種Vernam密碼形式,其本身不難被破解。另外三個階段一起提供了混淆、擴散和非線性功能。這三個階段沒有涉及密鑰,就它們自身而言,並未提供算法的安全性。然而,該算法經歷一個分組的XOR加密(輪密鑰加),再對該分組混淆擴散(其他三個階段),再接着又是XOR加密,如此交替進行,這種方式非常有效非常安全。
可逆原理:每個階段均可逆。對字節代替、行移位和列混淆,在解密算法中用它們相對應的逆函數。輪密鑰加的逆就是用同樣的輪密鑰和分組相異或,其原理就是A⊕B⊕B = A。和大多數分組密碼一樣,AES解密算法按逆序利用擴展密鑰,然而其解密算法和加密算法並不一樣,這是由AES的特定結構決定的。圖5.3中加密和解密流程在縱向上是相反的,在每個水平點上,state數組在加密和解密函數中都是一樣的。
四、AES的變換函數
1、字節代替變換
字節代替變換是一個簡單的查表操作。AES定義了一個S盒,它是由16×16個字節組成是矩陣,包含了8位所能表示的256個數的一個置換。State中每個字節按照如下方式映射為一個新的字節:把該字節的高4位作為行值,低4位作為列值,以這些數值為索引從S盒的對應位置取出元素作為輸出。如,十六進制數{95}所對應的S盒行值是9,列值是5。S盒中在此位置的值是{2A},相應的,{95}被映射為{2A}。
S盒的構造
(1)按字節值的升序逐行初始化S盒(相當於每個值都代表了坐標)
(2)把S盒的每個字節映射為它在有限域GF(28)中的逆
(3)把S盒中的每個字節的8個構成位記為(b7,b6,b5,b4,b3,b2,b1,b0)。對S盒的每個字節的每個位作如下變換:
bi’=b(i+4)mod8⊕b(i+5)mod8⊕b(i+6)mod8⊕b(i+7)mod8⊕ci (5.1)
這里ci 是指值為{63}的字節c的第i位。
AES標准用矩陣形式描述了這個變換:
逆字節代替變換則采用逆S盒,
逆S盒的構造
(1)按字節值的升序逐行初始化S盒
(2)利用式5.1的逆變換,該逆變換如下:
bi’=b(i+2)mod8⊕b(i+5)mod8⊕b(i+7)mod8⊕di (5.3)
這里di 是指值為{05}的字節d的第i位。也可以用矩陣形式描述:
(3)求其在GF(28)內的乘法逆
可逆證明:
令字節代替變換和逆字節代替變換中的矩陣分別為X和Y,常量c和d的向量表示分別為C和D。對於某個8位的向量B,式5.2變成了B’=XB⊕C。我們需證明Y(XB⊕C)⊕D=B
與DES加密的S盒的區別:
1、AES的S盒的原理是運用了GF(28)的乘法逆和矩陣的可逆運算來保證加密與解密過程的可逆性。DES的S盒設計主要是為了確保非線性關系,並不需要可逆。因而在設計理念上有極大的不同。
2、AES的S盒與DES的S盒形式上差別也很大,AES的S盒輸入和輸出的位數相同,均為128位,大小為16×16的字節矩陣,且只有1組;而DES的S盒輸入6位,輸出只有4位,大小是4×16的位矩陣,並且有8組。在輸入的坐標選擇規定上亦有不同。
2、行移位變換
操作本身很簡單,將state數組的第一行保持不變,第二行循環左移一個字節,第三行循環左移兩個字節,第四行循環左移三個字節。
其逆變換則將移位的幾行執行相反方向的移位操作即可。
基本原理
由於輪密鑰加、字節代替變換都是逐列地作用在state數組上,每一輪的行移位變換將會打亂列排列,使得保密性得到很大的提升。
3、列混淆變換
列混淆變換實際上是使用乘法矩陣(注意:其運算中涉及的加法和乘法都是定義在GF(28)上的加法和乘法,目的就是為了確保運算結果不會溢出定義域),可用以下式子描述。
逆向列混淆變換可由如下矩陣乘法定義
其可逆性可以簡單運算得到證明
基本原理
式5.3中矩陣的系數是基於碼字間有最大距離的線性編碼,這使得在每列的所有字節中有良好的混淆性。列混淆變換和行移位變換使得經過幾輪變換后,所有的輸入位和所有的輸出位相關。
此外,列混淆變換的系數,即{01}{02}{03}是基於算法實現角度考慮的。不過,逆向列混淆變換的系數則更加難以實現,然而加密被視為比解密更重要,因為:
1、對於CFB和OFB密碼模式,僅用到加密算法
2、和任何其他分組密碼一樣,AES能用於構造消息驗證碼,這僅僅用到了加密過程。
4、輪密鑰加變換
這個比較簡單,沒有太多好說的,密鑰擴展的復雜性是確保算法安全性的重要部分。
以下是描述單輪AES的另一個視角,強調各變換的機制和輸入。
五、AES的密鑰擴展
AES密鑰擴展算法的輸入值是4個字(16字節),輸出值是一個由44個字組成(176字節)的一維線性數組。以下偽碼描述了這個擴展:
KeyExpansion(byte key[16], word w[44]){
word temp
for(i=0; i<4; i++) //將輸入的密鑰直接復制到擴展密鑰數組的前四個字
w[i]=word(key[4*i],key[4*i+1],key[4*i+2],key[4*i+3]);
temp = w[i-1];
if(i mod 4 == 0) //對w數組下標為4的倍數的元素采用更復雜的函數來計算
temp = SubWord(RotWord(temp))⊕Rcon[i/4];
w[i] = w[i-4] + temp; //每一個新增的字w[i]依賴於w[i-1] 和w[i-4]
}
RotWord的功能是字循環,即使一個字的4個字節循環左移1個字節。
SubWord是利用S盒對輸入字的每個字節進行字節代替。
Rcon[i]是輪常量,代表一個字,這個字最右邊三個字節總是0,因此字與Rcon異或,其結果只是與該字最左邊的那個字節相異或。每一輪的輪常量都不相同,其定義為
Rcon[i] = (RC[i],0,0,0),其中RC[1] = 1,RC[i] = 2•RC[i-1] 乘法是定義在域GF(28)上的。
RC[i]的值按照十六進制表示為
輪常量取不同值就是為了消除不同輪密鑰產生方式上的對稱性或相似性。
密鑰擴展算法的設計規范:
1、找到密鑰或輪密鑰的部分位不足以計算出輪密鑰的其他位;
2、它是一個可逆的變換(即知道擴展密鑰中任何連續的Nk個字能夠重新產生整個擴展密鑰,Nk是構成密鑰所需的字數);
3、能夠在各種處理器上有效地執行;
4、使用輪常量消除對稱性;
5、將密鑰差異性擴散到輪密鑰中的能力,即密鑰的每個位能影響輪密鑰的許多位;
6、足夠的非線性以防止輪密鑰的差異完全由密鑰的差異所決定。
改進--等價的逆算法
上文所述的標准解密流程與標准加密流程並不完全一致,加密每一輪的流程是:字節代替-->行移位-->列混淆-->輪密加。而解密每一輪的流程是:逆向行移位-->逆向字節代替-->輪密加-->逆向列混淆。
可以對解密構成進行改進,使得解密流程與加密流程等效。
1、交換逆向行移位和逆向字節代替:
由於逆向行移位並不影響state數組中字節的內容,而逆向字節代替也不會影響state數組中字節的位置,因而兩者可以交換順序而不影響解密。
2、交換輪密鑰加和逆向列混淆:
這兩種操作均不會改變state中字節的順序,給定狀態Si和給定輪密鑰wi,可證明
逆向列混淆(Si⊕wi)= [逆向列混淆(Si)]⊕[逆向列混淆(wi)]
這個等式顯然是正確的,因而如果要改變這兩種操作的順序,則必須改進逆向列混淆的操作,即先對輪密鑰應用逆向列混淆(注意,無需對首尾的輪密鑰應用逆向列混淆)。最終,改進后的解密流程如下圖: