AES是一種對稱式加密算法
AES的列混淆(MixColume)中會用到伽羅瓦域的加法和乘法
有限域中的元素集合是有限的,表示為,p是一個質數(素數)。EX ,表示包含256個元素的有限域(其中元素可由0~p^n-1表示)
當n=1時可稱為素域,在中,所有的非0元素都有逆元素(反元素)。
其運算規則如下
p^n不為質數時,這樣的有限域加法和乘法就不能用整數加法和整數乘法mod p表示。擴展域有不同的規則執行運算(以下例子以AES中會用到的GF(2)舉例)
在擴展域的多項式表示
EX的每個元素都可表示為
(講白話就是a用0 1表示)
每一位分別進行加法後mod 2(和一般二進位加法不同,不需要進位)
假設 (x已省略)
則
在GF(2^n)下A-B和A+B是一樣的,且都與XOR等價
設
則係數們
.
.
.
其實就是一般的多項式乘法(記得要mod)
但是C(x)的次數通常會大於n,所以要化簡,和素數超過範圍時mod一個素數一樣。這裡要將乘出來的多項式除一個不能約分的多項式,算出的餘式就是最後的結果(在AES中使用的是)
有四種操作,分別是金鑰加密(Add Round Key)、位元組代換(SubByte)、行位移(Shift Rows)、列混淆(Mix Column)
明文和金鑰都是128位的(密鑰也可以192位256位,下面都已128為主),16個字節由上到下由左到右排成4*4
總共進行10輪處理,只有最後一輪少了一次MixColumn
流程圖
而解密就只是完全反過來而已
明文的矩陣和密鑰的矩陣進行XOR運算(其實就是擴展域的加法)
S_box是一個有256個字節組成的陣列
這層的功能就是將輸入通過S_box代換成另一個字節
對應方法為,將輸入字節的高4位和低4位分別作為行索引和列索引,根據這接索引在S_box中找到對應的值(實作時可以將S_Box存成一維的,這樣就直接將值作為索引就好)
加密與解密時使用的S_box不同(戶違反矩陣)
S-box
來源:wiki https://en.wikipedia.org/wiki/Rijndael_S-box
Inv S-box
來源wiki https://en.wikipedia.org/wiki/Rijndael_S-box
將4*4的矩陣進左右的位移
p1 | p5 | p9 | p13 |
p2 | p6 | p10 | p14 |
p3 | p7 | p11 | p15 |
p4 | p8 | p12 | p16 |
p1 | p5 | p9 | p13 |
p6 | p10 | p14 | p2 |
p11 | p15 | p3 | p7 |
p16 | p4 | p8 | p12 |
第一行不移
第二行向左移1格
第三行向左移2格
第四行向左移3格
InvShiftRows就是移回去(還原)
在正向的列混淆中,要將輸入的矩陣左乘一個的Mix矩陣(其乘法與加法在中進行)
逆向的做法一樣只是將左乘的矩陣換成的Mix的反矩陣
流程圖
來源:https://www.slideserve.com/keegan/chapter-5#google_vignette
其中,g函式就是實作中的KeyScheduleCore
在加密時不可能只加密128bit,明文可能會很長
而ECB是處理這個問題最簡單的模式(除次之外還有CBC,CTR,CFB,OFB)
但也是最不安全的,因為一樣的明文塊會加密出一樣的密文
ECB的處裡方式非常簡單,就是將明文每128bit切成一塊,並分別加密。
加密時一定會遇到明文大小不是16的倍數的情況,這時就需要填充。
而pkcs7的填充方法也很簡單,假設現在差一個字就能成為16的倍數,那就填充0x01,差兩個就填充兩個0x02,…差15個就填充15個0x0f,比較特別的是如果剛剛好是16的倍數,擇要填充16個0x10。u因為去除填充時需要以最後一個字元作為依據,來判定需要刪除多少字,例如最後一個是0x04那就知道倒數4個字都是填充,可以刪掉,所以填充0x010也是必要的
實際實作上還有很多細節,(包括ECB的處理、Base64的使用等)
可以到github詳細觀看:https://github.com/samsonjaw/AES