AES加密算法

,AES的基本要求是:比三重DES快、至少與三重DES同樣安全、數據分組長度爲128-bit、密鑰長度爲128/192/256-bit,對應於密鑰的不一樣長度,加密輪的次數也不盡相同。選定Rijndael算法爲新的AES算法。算法的原型是Square算法,其設計策略爲寬軌跡策略(針對差分分析和線性分析提出的,最大優勢是能夠給出算法的最佳差分特徵的機率以及最佳線性逼近的誤差的界;由此能夠分析算法抵抗差分密碼分析以及線性密碼分析的能力。)算法

AES加密標準是當下最普遍使用的對稱密鑰加密體系。AES加密標準已經普遍應用在互聯網安全領域,譬如IPsec、TLS、Wi-Fi加密標準IEEE 802.11i、SSH、Skype等領域。數組

Rijndael設計思想

Rijndael沒有Feistel結構,其輪函數是由三個不一樣的可逆均勻變換(每一個比特都是用相似的方法進行處理的)組成的,稱它們爲3個「層」。不一樣的層選擇的大部分是創建在「寬軌跡策略」的應用基礎之上。安全

  • 線性混合層 確保多輪之上的高度擴散
  • 非線性層 將具備最優的「最壞狀況非線性特徵」的S盒並行使用
  • 密鑰加密 單輪子密鑰簡單地異或到中間狀態上,實現一次性掩蓋

在第一輪以前,用了一個初始密鑰加層(其目的爲在不知道密鑰的狀況下,對最後一個密鑰加層之後的任一曾可簡單地剝去,所以初始密鑰加層對密碼的安全性無任何意義。爲了使加密算法和解密算法在結構上更加接近,最後一輪的線性混合曾與前面各輪的線性混合層不一樣,這相似於DES的最後一輪不作左右交換(這種設計不以任何方式提升或下降該密碼的安全性)函數

Rijndael算法說明

該算法是一個迭代型分組密碼,分組長度和密鑰長度均可改變,各自能夠獨自地制定爲128-bit、192-bit、256-bit加密

狀態、種子密鑰和輪數

算法的中間結果須要進行分組,稱該分組爲狀態。全部的操做都在狀態上進行。狀態能夠用以字節爲元素的矩陣陣列表示,該陣列有4行,列數計爲Nb。Nb等於分組長度除以32。設計

種子密鑰相似地用一個以字節爲元素的矩陣陣列表示,該陣列有4行,列數記爲Nk,Nk等於分組長度除以32。code

固然,能夠將這些分組當作一維數組,數組中的每個元素是上述陣列中的四個字節元素組成的列向量,顯然,數組的長度能夠分爲4,6,8三種。四個字節的元素構成的列向量有時也稱爲字。原型

算法的輸入和輸出被看做是由8-bit字節構成的一維數組,其元素的下標範圍爲0~(4Nb-1),所以,輸入和輸出以字節爲單位的分組長度分別爲16,24和32。輸入的種子密鑰也堪稱是由8-bit字節構成的一維數組,其下標的範圍爲0~(4Nb-1)。所以,種子密鑰以字節爲單位的分組長度也分別爲16,24和32。it

算法的輸入是以字節爲單位,按照列優先的順序依次填入矩陣中。密鑰也是同樣。而輸出也一樣是依照相同的順序取出。io

迭代的輪數計爲Nr,該數值與Nb和Nk相關

Nr Nb=4 Nb=6 Nb=8
Nk=4 10 12 14
Nk=6 12 12 14
Nk=8 14 14 14

輪函數

Rijndael的輪函數由4個不一樣的計算部件組成:字節代換(ByteSub)、行移位(ShiftRow)、列混合(MixColumn)、密鑰加(AddRoundKey)

字節代換

字節代換是非線性變換,獨立地對狀態的每一個字節進行。代換表(S-Box)是可逆的。

  1. 將字節看做GF(2^8)上的元素,映射到本身的乘法逆元,'00'映射到本身。(能夠經過矩陣計算得出)
  2. 對字節作仿射變換

行移位

將狀態陣列的各行進行循環移位,不一樣用的狀態行的位移量不一樣。第0行不移動,第1行循環左移C1個字節,第二行循環左移C2個字節,第三行循環左移C3個字節。

Nb C1 C2 C3
4 1 2 3
6 1 2 3
8 1 3 4

列混合

列混合是AES中主要的Diffusion工序。其方式爲對於每個列,乘以一個4×4的矩陣。再加上一個相關的係數向量。

密鑰加

密鑰加時將輪密鑰簡單地與狀態進行逐行比特異或。輪密鑰由種子密鑰經過密鑰編排算法獲得,輪密鑰長度等於分組長度Nb

密鑰編排

由密鑰擴展和輪密鑰選取兩部分組成,其基本原則以下

  • 輪密鑰的比特數等於分組長度乘以輪數加1
  • 種子密鑰被擴展成爲擴展密鑰
  • 輪密鑰從擴展密鑰中取,其中第一輪輪密鑰取擴展密鑰的前Nb個字,第2輪輪密鑰去接下來的Nb個字,如此下去。

密鑰擴展

擴展密鑰以4字節爲元素的一維陣列
擴展算法會根據Nk<=6和Nk>6有不一樣
當Nk<=6時,擴展算法以下:

KeyExpansion(byte Key[4 * Nk], W[Nb * (Nr + 1]){
    for(i = 0; i < Nk; i++){
        W[i] = (Key[4 * i], Key[4 * i + 1], Key[4 * i + 2], Key[4 * i + 3]);
    for(i = Nk; i < Nb * (Nr + 1); i++){
        temp = W[i - 1];
        if(i % Nb == 0) temp = SubByte(RotByte(temp))^Rcon[i / Nk];
    W[i] = W[i - Nk] ^ temp;

其中Key[4 * Nk]爲種子密鑰。函數SubByte返回4字節字,其中每個字節都是用Rijndael的S盒做用到輸入字對應的字節獲得。函數RotByte也返回4字節字,由輸入的字循環移位獲得。

當Nk>6時,擴展算法以下:

KeyExpansion(byte Key[4 * Nk], W[Nb * (Nr + 1]){
    for(i = 0; i < Nk; i++){
        W[i] = (Key[4 * i], Key[4 * i + 1], Key[4 * i + 2], Key[4 * i + 3]);
    for(i = Nk; i < Nb * (Nr + 1); i++){
        temp = W[i - 1];
        if(i % Nb == 0) temp = SubByte(RotByte(temp))^Rcon[i / Nk];
    W[i] = W[i - Nk] ^ temp;
相關文章
相關標籤/搜索