密碼學——AES加密算法
AES加密算法就是眾多對稱加密算法中的一種,它的英文全稱是Advanced Encryption Standard,翻譯過來是高級加密標准,它是用來替代之前的DES加密算法的。AES加密算法采用分組密碼體制,每個分組數據的長度為128位16個字節,密鑰長度可以是128位16個字節、192位或256位,一共有四種加密模式,我們通常采用需要初始向量IV的CBC模式,初始向量的長度也是128位16個字節。
概念
域的概率及性質
形象地說,域有這樣一個性質:在加法和乘法上具有封閉性。也就是說對域中的元素進行加法或乘法運算后的結果仍然是域中的元素。
域有單位元和逆元兩個概念。加法和乘法運算都有對應的單位元(這兩個單位元一般不同,但都用符號e表示)。單位元就像線性代數的單位矩陣。一個矩陣乘以單位矩陣等於本身。對應地,在域中的單位元有:對於加法單位元,所有元素加上單位元e,等於其本身。對應乘法單位元,所有元素乘上單位e,等於其本身。
逆元就像數學上的倒數,兩個元素互為對方的逆元。如果元素a和b互為加法逆元,那么就有 a + b = e。若互為乘法逆元,那么就有a * b = e。如果元素a在域中找不到另外一個元素b,使得a+b=e(a*b=e),那么a就沒有加法(乘法)逆元。。
有限域GF(p)
在密碼學中,有限域GF(p)是一個很重要的域,其中p為[素數](javascript:void())。簡單來說,GF(p)就是 mod p,因為一個數 模p后,結果在[0, p-1]之間。對於元素a和b,那么(a+b) mod p和(a*b)mod p,其結果都是域中的元素。GF(p)里面的加法和乘法都是平時用的加法和乘法。GF(p)的加法和乘法單位元分別是0和1,元素的加法和乘法逆元都很容易理解和求得。
GF(2^8)的加法和乘法
加法就是經典的異或運算;乘法則稍復雜一些,對於一個8位的二進制數來說,使用域上的乘法乘以(00000010)等價於左移1位(低位補0)后,再根據情況同(00011011)進行異或運算,設S1 = (a7 a6 a5 a4 a3 a2 a1 a0),剛0x02 * S1如下圖所示:
也就是說,如果a7為1,則進行異或運算,否則不進行。
類似地,乘以(00000100)可以拆分成兩次乘以(00000010)的運算:
乘以(0000 0011)可以拆分成先分別乘以(0000 0001)和(0000 0010),再將兩個乘積異或:
因此,我們只A需要實現乘以2的函數,其他數值的乘法都可以通過組合來實現。
AES加密流程
AES 加密算法A大致分為 4 個步驟:
(1)字節替代
(2)行移位
(3)列混淆
(4)輪密相加
加解密中每輪的密鑰分別由初始密鑰擴展得到。算法中16字節的明文、密文和輪密鑰都以一個4x4的矩陣表示。加密流程圖如下:
下面詳細介紹每一種操作
-
字節代換
字節代替的主要功能是通過S盒完成一個字節到另外一個字節的映射。下圖(a)為S盒,圖(b)為S-1(S盒的逆)。
\(S\)和\(S^{-1}\)分別為16x16的矩陣。假設輸入字節的值為a=a7a6a5a4a3a2a1a0,則輸出值為S[a7a6a5a4][a3a2a1a0],S-1的變換也同理。
-
行移位
行移位的功能是實現一個4x4矩陣內部字節之間的置換。
正向行移位的原理圖如下:
實際移位的操作即是:第一行保存不變,第二行循環左移1個字節,第三行循環左移2個字節,第四行循環左移3個字節。假設矩陣的名字為state,用公式表示如下:\(state[i][j] = state[i][(j+i)%4];\)其中i、j屬於[0,3]。
逆向行移位即是相反的操作,用公式表示如下:\(state[i][j] = state[i][(4+j-i)%4]\);其中i、j屬於[0,3]。
-
列混淆
列混淆:利用\(GF(2^8)\)域上算術特性的一個代替,正向列混淆的原理圖如下:
根據矩陣的乘法可知,在列混淆的過程中,每個字節對應的值只與該列的4個值有關系。此處的乘法和加法都是定義在GF(28)上的,需要注意如下幾點:
-
將某個字節所對應的值乘以2,其結果就是將該值的二進制位左移一位,如果該值的最高位為1(表示該數值不小於128),則還需要將移位后的結果異或00011011
-
乘法對加法滿足分配率,例如:\(07·S_{0,0}=(01⊕02⊕04)·S_{0,0}= S0,0⊕(02·S_{0,0}(04·S_{0,0})\)
-
此處的矩陣乘法與一般意義上矩陣的乘法有所不同,各個值在相加時使用的是模2加法(相當於是異或運算)。
-
-
輪密相加
任何數和自身的異或結果為0。加密過程中,每輪的輸入與輪密鑰異或一次;因此,解密時再異或上該輪的密鑰即可恢復輸入。
-
密鑰擴展
密鑰擴展的原理圖如下:
密鑰擴展過程說明:
- 將初始密鑰以列為主,轉化為4個32 bits的字,分別記為w[0…3];、
- 按照如下方式,依次求解w[j],其中j是整數並且屬於[4,43];
- 若j%4=0,則w[j]=w[j-4]⊕g(w[j-1]),否則w[j]=w[j-4]⊕w[j-1];
函數g的流程說明:
- 將w循環左移一個字節;
- 分別對每個字節按S盒進行映射;
- 與32 bits的常量(RC[j/4],0,0,0)進行異或,RC是一個一維數組,其值如下。(RC的值只需要有10個,而此處用了11個,實際上RC[0]在運算中沒有用到,增加RC[0]是為了便於程序中用數組表示。由於j的最小取值是4,j/4的最小取值則是1,因此不會產生錯誤。)
RC = {00, 01, 02, 04, 08, 10, 20, 40, 80, 1B, 36}
Python實現
密碼學——AES加密算法
AES加密算法就是眾多對稱加密算法中的一種,它的英文全稱是Advanced Encryption Standard,翻譯過來是高級加密標准,它是用來替代之前的DES加密算法的。AES加密算法采用分組密碼體制,每個分組數據的長度為128位16個字節,密鑰長度可以是128位16個字節、192位或256位,一共有四種加密模式,我們通常采用需要初始向量IV的CBC模式,初始向量的長度也是128位16個字節。
概念
域的概率及性質
形象地說,域有這樣一個性質:在加法和乘法上具有封閉性。也就是說對域中的元素進行加法或乘法運算后的結果仍然是域中的元素。
域有單位元和逆元兩個概念。加法和乘法運算都有對應的單位元(這兩個單位元一般不同,但都用符號e表示)。單位元就像線性代數的單位矩陣。一個矩陣乘以單位矩陣等於本身。對應地,在域中的單位元有:對於加法單位元,所有元素加上單位元e,等於其本身。對應乘法單位元,所有元素乘上單位e,等於其本身。
逆元就像數學上的倒數,兩個元素互為對方的逆元。如果元素a和b互為加法逆元,那么就有 a + b = e。若互為乘法逆元,那么就有a * b = e。如果元素a在域中找不到另外一個元素b,使得a+b=e(a*b=e),那么a就沒有加法(乘法)逆元。。
有限域GF(p)
在密碼學中,有限域GF(p)是一個很重要的域,其中p為[素數](javascript:void())。簡單來說,GF(p)就是 mod p,因為一個數 模p后,結果在[0, p-1]之間。對於元素a和b,那么(a+b) mod p和(a*b)mod p,其結果都是域中的元素。GF(p)里面的加法和乘法都是平時用的加法和乘法。GF(p)的加法和乘法單位元分別是0和1,元素的加法和乘法逆元都很容易理解和求得。
GF(2^8)的加法和乘法
加法就是經典的異或運算;乘法則稍復雜一些,對於一個8位的二進制數來說,使用域上的乘法乘以(00000010)等價於左移1位(低位補0)后,再根據情況同(00011011)進行異或運算,設S1 = (a7 a6 a5 a4 a3 a2 a1 a0),剛0x02 * S1如下圖所示:
也就是說,如果a7為1,則進行異或運算,否則不進行。
類似地,乘以(00000100)可以拆分成兩次乘以(00000010)的運算:
乘以(0000 0011)可以拆分成先分別乘以(0000 0001)和(0000 0010),再將兩個乘積異或:
因此,我們只A需要實現乘以2的函數,其他數值的乘法都可以通過組合來實現。
AES加密流程
AES 加密算法A大致分為 4 個步驟:
(1)字節替代
(2)行移位
(3)列混淆
(4)輪密相加
加解密中每輪的密鑰分別由初始密鑰擴展得到。算法中16字節的明文、密文和輪密鑰都以一個4x4的矩陣表示。加密流程圖如下:
下面詳細介紹每一種操作
-
字節代換
字節代替的主要功能是通過S盒完成一個字節到另外一個字節的映射。下圖(a)為S盒,圖(b)為S-1(S盒的逆)。
\(S\)和\(S^{-1}\)分別為16x16的矩陣。假設輸入字節的值為a=a7a6a5a4a3a2a1a0,則輸出值為S[a7a6a5a4][a3a2a1a0],S-1的變換也同理。
-
行移位
行移位的功能是實現一個4x4矩陣內部字節之間的置換。
正向行移位的原理圖如下:
實際移位的操作即是:第一行保存不變,第二行循環左移1個字節,第三行循環左移2個字節,第四行循環左移3個字節。假設矩陣的名字為state,用公式表示如下:\(state[i][j] = state[i][(j+i)%4];\)其中i、j屬於[0,3]。
逆向行移位即是相反的操作,用公式表示如下:\(state[i][j] = state[i][(4+j-i)%4]\);其中i、j屬於[0,3]。
-
列混淆
列混淆:利用\(GF(2^8)\)域上算術特性的一個代替,正向列混淆的原理圖如下:
根據矩陣的乘法可知,在列混淆的過程中,每個字節對應的值只與該列的4個值有關系。此處的乘法和加法都是定義在GF(28)上的,需要注意如下幾點:
-
將某個字節所對應的值乘以2,其結果就是將該值的二進制位左移一位,如果該值的最高位為1(表示該數值不小於128),則還需要將移位后的結果異或00011011
-
乘法對加法滿足分配率,例如:\(07·S_{0,0}=(01⊕02⊕04)·S_{0,0}= S0,0⊕(02·S_{0,0}(04·S_{0,0})\)
-
此處的矩陣乘法與一般意義上矩陣的乘法有所不同,各個值在相加時使用的是模2加法(相當於是異或運算)。
-
-
輪密相加
任何數和自身的異或結果為0。加密過程中,每輪的輸入與輪密鑰異或一次;因此,解密時再異或上該輪的密鑰即可恢復輸入。
-
密鑰擴展
密鑰擴展的原理圖如下:
密鑰擴展過程說明:
- 將初始密鑰以列為主,轉化為4個32 bits的字,分別記為w[0…3];、
- 按照如下方式,依次求解w[j],其中j是整數並且屬於[4,43];
- 若j%4=0,則w[j]=w[j-4]⊕g(w[j-1]),否則w[j]=w[j-4]⊕w[j-1];
函數g的流程說明:
- 將w循環左移一個字節;
- 分別對每個字節按S盒進行映射;
- 與32 bits的常量(RC[j/4],0,0,0)進行異或,RC是一個一維數組,其值如下。(RC的值只需要有10個,而此處用了11個,實際上RC[0]在運算中沒有用到,增加RC[0]是為了便於程序中用數組表示。由於j的最小取值是4,j/4的最小取值則是1,因此不會產生錯誤。)
RC = {00, 01, 02, 04, 08, 10, 20, 40, 80, 1B, 36}