背景
AES加密的幾種模式
基本運算
AES加密原理
Matlab實現(xiàn)
Verilog實現(xiàn)
Testbench
本文首發(fā)于公眾號【兩猿社】,重點講述了AES加密算法的加密模式和原理,用MATLAB和Verilog進行加解密的實現(xiàn)。
美劇《硅谷》第六季居然已經(jīng)完結(jié)了!小猿追了6年的劇就這么結(jié)束了,然而結(jié)局感覺并不那么喜劇。比爾·蓋茨和Twitter前CEO也在最后一集本色出演了。
《硅谷》每一季的內(nèi)容都緊跟當(dāng)時科技前沿,最后一季也不例外,焦點聚集于信息安全。經(jīng)過Richard升級之后的超級AI—Son of Anton2.0,因為能自動破解現(xiàn)存世界上任何一種加密算法,使得世界上再無隱私可言,而迫使Pied Piper宣布解散,至此全季終。劇中提到了一種加密算法:ECC P-256。
ECC是橢圓曲線密碼學(xué)(Elliptic Curve Cryptography)的簡稱,而P-256是“P-256”橢圓曲線。
聽上去挺唬人,這個P-256加密安全性怎么樣呢?
早在2011年,美國國家標(biāo)準(zhǔn)技術(shù)研究院(NIST)審查了有關(guān)攻擊密碼算法的學(xué)術(shù)文獻,并對不同算法提供的實際安全性提出了建議。
可以看到,P-256的安全性和AES-128等同。在同等密鑰長度密鑰條件下,AES的加密安全性超過Hash、RSA和ECC。
AES加密究竟是個什么算法呢?
廢話不多說,我們直接進入正題!
(小猿盡可能用淺顯易懂的方式講解,但文中也不可避免的出現(xiàn)了一些公式和計算,篇幅較長,具有一定專業(yè)性。如果您僅想要獲取源碼,請直接跳到文末。)
*ps:*關(guān)注公眾號【兩猿社】,回復(fù)【AES】可獲取Matlab和Verilog源碼,還有NIST FIPS原版AES spec哦!
隨著5G等高新技術(shù)的快速普及,大眾生活水平和認(rèn)知的同步提高,信息安全逐漸引起普通受眾的重視。再加上硬件加密相比軟件加密的天生優(yōu)勢,國內(nèi)加密芯片也開始嶄露頭角,在IC行業(yè)中擁有了一席之位。
AES (Advanced Encryption Standard)是由NIST標(biāo)準(zhǔn)化的對稱分組密碼,是對稱加密事實上的標(biāo)準(zhǔn)(上文提到的ECC屬于非對稱加密)。由于上一代的DES算法密鑰長度?。?6bits),容易被破解而被AES取代??梢园l(fā)現(xiàn),目前市面上幾乎所有的大型SOC芯片中,AES的身影必不可少。
在AES中,數(shù)據(jù)塊固定128bits長度,加解密的密鑰長度有三種,分別是128bits,192bits和256bits。本文以AES-128bits為例講解。其他兩種密鑰長度在實現(xiàn)上僅是密鑰擴展和輪數(shù)的差別。
將以32bits為一個字長進行分組,由于數(shù)據(jù)固有128bits,數(shù)據(jù)的分組長度Nb常為4,密鑰分組長度Nk分別為4(128bits)、6(192bits)和8(256bits)。
[外鏈圖片轉(zhuǎn)存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-hly75dcA-1583044212984)(https://upload-images.jianshu.io/upload_images/21180371-f1d19552e8aa8bb7?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)]
AES加密的幾種模式
ECB是最簡單的塊密碼加密模式,加密前根據(jù)加密塊大?。ㄈ鏏ES為128位)分成若干塊,將使用相同的密鑰和相同的算法對每個塊進行加密,解密同理。
ECB模式由于每塊數(shù)據(jù)的加密是獨立的,因此加密和解密都可以并行計算,ECB模式最大的缺點是加密相同的明文會得到相同的密文。
CBC模式對于每個待加密的密碼塊在加密前會先與前一個密碼塊的密文異或然后再用加密器加密。第一個明文塊與初始化向量(IV)異或,IV具有與加密塊相同的大小。通常,IV是隨機數(shù),而不是定數(shù)。
明文分為多個塊,需要添加填充數(shù)據(jù)。首先,我們將對IV使用明文塊異或。然后,將結(jié)果經(jīng)過AES核加密得到密文塊。在下一個塊中,將使用加密結(jié)果與明文塊進行異或,一直到最后一個塊。
在這種模式下,即使加密相同的明文塊,也將獲得不同的密文塊。
與ECB和CBC模式只能夠加密塊數(shù)據(jù)不同,CFB能夠?qū)K密文(Block Cipher)轉(zhuǎn)換為流密文(Stream Cipher),它仍需要IV。
首先,需加密IV,將其與明文塊進行異或運算得到密文。然后將加密結(jié)果再加密,與明文進行異或。由于此模式不會直接加密明文,僅使用密文與明文進行異或運算以獲取密文。因此,在這種模式下,不需要填充數(shù)據(jù)。
而且它可以并行解密數(shù)據(jù)。此模式類似于CBC,如果有壞塊,它將影響所有后續(xù)塊。
OFB是先用塊加密器生成密鑰流(Keystream),然后再將密鑰流與明文流異或得到密文流,解密是先用塊加密器生成密鑰流,再將密鑰流與密文流異或得到明文,由于異或操作的對稱性所以加密和解密的流程是完全一樣的。
它與CFB不同,它始終對IV進行加密。它不能并行加密/解密IV。
在CTR操作模式下,計數(shù)值作為加密器(Encrypt)的輸入塊,即為IV,計數(shù)器的值(Counter,Counter + 1,…,Counter + N – 1)被加密。它也是流加密器。
計數(shù)器的大小與所用塊的大小相同。如圖所示,將加密器的輸出塊與明文塊異或。所有加密塊都使用相同的加密密鑰。這種模式下,它不會受到壞塊的影響。非常像OFB模式。但是CTR每次都會使用計數(shù)器進行加密,而不是使用IV。因此,如果可以直接獲得計數(shù)器,則可以并行加密/解密數(shù)據(jù)。
注:上文所提到的塊加密器即FIPS第197號文中所描述的 AES加密算法,即AES加密核。
咳咳,好了,上面是什么玩意兒不管了,沒關(guān)系,讓我們重新開始學(xué)加法和乘法吧…
行行行,你看一遍能懂算我輸。
AES算法中,所涉及到的計算都是在有限域GF(
2
8
2^8
28)上的。
GF(
2
8
2^8
28)域是由8位2進制數(shù)組成,其空間大小為256(00~ff),因此記為
2
8
2^8
28。
在有限域中進行的加法運算和乘法運算不同于我們平常使用的基本算術(shù)運算,下面是它的幾個特點:
單比特的相加實則是異或操作。
1⊕1=0
1⊕0=1
0⊕0=0
多比特相加則對應(yīng)系數(shù)異或:
有限域GF( 2 8 2^8 28)上的乘法運算較為復(fù)雜,依然滿足分配律和結(jié)合律。
GF( 2 8 2^8 28)域中的兩個多項式做乘法后,其最高次項會在0~14之間,需要對一個最高次項為8的固定不可約分多項式取模。
在AES算法中運算都是以字節(jié)為單位的,其不可約分多項式固定為
m
(
x
)
=
x
8
+
x
4
+
x
3
+
x
+
1
m(x)=x^8+x^4+x^3+x+1
m(x)=x8+x4+x3+x+1
二進制形式表示為{0000001}{00011011},十六進制為{01}{1b}
。
取模運算后使最終結(jié)果的多項式x的最高次項不大于7,才能適應(yīng)AES算法的字節(jié)運算要求。如果做乘法之后的最高次項不大于7,則不需要做取模運算。
由于有限域中乘法運算符合交換律和分配律,多項式與任何數(shù)的乘法運算都可以分解為多個乘{02}與{01}后的有限域加法運算,與{02}的乘法運算可以用移位實現(xiàn),與{01}的乘法運算結(jié)果則是其本身。
AES算法中每個計算單位都是8位,乘法分解之后最高次項最大為
x
8
x^8
x8(
x
7
x^7
x7·{02}),移位后的等效多項式如下:
m
(
x
)
=
b
7
x
8
+
b
6
x
7
+
b
5
x
6
+
b
4
x
5
+
b
3
x
4
+
b
2
x
3
+
b
1
x
2
+
b
0
x
m(x)=b_7x^8+b_6x^7+b_5x^6+b_4x^5+b_3x^4+b_2x^3+b_1x^2+b_0x
m(x)=b7?x8+b6?x7+b5?x6+b4?x5+b3?x4+b2?x3+b1?x2+b0?x
如果 x 8 x^8 x8項系數(shù) b 7 b_7 b7?為0,則證明結(jié)果無溢出;為1則證明結(jié)果溢出,需要與{01}{1b}取模運算。由于已經(jīng)事先知道最高項為8次方項,與{01}取模后的結(jié)果為0。因此只用考慮與{1b}的取模運算,而最高次項此時最大為7次方,與{1b}的取模運算和異或操作等同。
加法很簡單吧,你說什么,乘法看不懂?沒關(guān)系,接著往下看。
AES-128bits加密算法中共有十輪迭代變換,每一輪迭代包含4個計算,分別是字節(jié)替換(SubBytes)、行移位(ShiftRows)、列混合(MixColumns)及輪密鑰加(AddRoundKey)。
可以表示為:
Round (State,RoundKey)
{
SubBytes (state);
ShiftRows (state);
MixColumns (state);
AddRoundKey(state);
}
明文在輸入加密核之后,經(jīng)過第一次輪密鑰加,開始輪函數(shù)的迭代,即依次通過字節(jié)替換,行移位,列混合和輪密鑰加運算;而在最后一輪即第十輪變換時,省去了列混合這一步驟。
解密的步驟剛好相反,順序不同。密文通過一次輪密鑰加之后,進入解密輪函數(shù),依次是行移位,字節(jié)替換,輪密鑰加和列混合的逆運算(由于輪密鑰加為異或運算,其逆運算也是異或運算,所以它的逆運算不變),最后一輪同樣也沒有逆列混合。
注意加密和解密所用的擴展后密鑰順序是相反的,且加解密的最后一個操作都是輪密鑰加,這樣可以防止攻擊者繞過密鑰而直接對系統(tǒng)進行攻擊,使算法具有很好的安全性。
字節(jié)替換(SubBytes)是AES算法中惟一的非線性運算,使用替換表(S-Box)對矩陣中的每一個字節(jié)元素進行獨立運算。且s-box是可逆的。為了實現(xiàn)方便,使用S-Box替換的方式進行。verilog中使用查找表實現(xiàn)。
轉(zhuǎn)換方式為:假設(shè)輸入的字節(jié)為{
a
7
a_7
a7?
a
6
a_6
a6?
a
5
a_5
a5?
a
4
a_4
a4?
a
3
a_3
a3?
a
2
a_2
a2?
a
1
a_1
a1?
a
0
a_0
a0?}
則經(jīng)過S-Box之后的輸出值為S[
a
7
a_7
a7?
a
6
a_6
a6?
a
5
a_5
a5?
a
4
a_4
a4?][
a
3
a_3
a3?
a
2
a_2
a2?
a
1
a_1
a1?
a
0
a_0
a0?]
例如:如輸入二進制字節(jié)為{10110100},十六進制為{B4},參照S-Box替換表替換后的值為S[B][4]=8D,再經(jīng)過Inverse S-Box可得到替換前的值 =B4(AES解密中的逆變換會在下一篇講解)。
行移位(ShiftRows)是實現(xiàn)4×4矩陣內(nèi)部字節(jié)的置換。
實際操作是:第零行不改動,將第一行每個字向左循環(huán)移1 byte,第二行每個字向左循環(huán)移2 byte,第三行每個字向左循環(huán)移3 byte。
列混合(MixColumns)是對GF(
2
8
2^8
28)域某些算術(shù)性質(zhì)的等效,是狀態(tài)矩陣與域中一個固定多項式做乘法運算,然后與多項式(
x
4
+
1
x^4+1
x4+1)取模,其中固定多項式a(x)為:
a
(
x
)
=
(
03
)
x
3
+
(
01
)
x
2
+
(
01
)
x
+
(
02
)
a(x)=(03)x^3+(01)x^2+(01)x+(02)
a(x)=(03)x3+(01)x2+(01)x+(02)
()中的數(shù)為十六進制字節(jié)。則列混合表示為:
s
′
(
x
)
=
a
(
x
)
·
s
(
x
)
s'(x)=a(x)·s(x)
s′(x)=a(x)·s(x)
用矩陣乘法表示為:
可以看出,固定矩陣的值由3個十六進制字節(jié)組成,即{01}、{02}、{03},列混合中的加法運算和乘法運算都是有限域中的算術(shù)運算。所以符合以下規(guī)則:
- 某個字節(jié)的值乘以{02},則是將該字節(jié)向左移1 bit,如果該字節(jié)最高位為1(移位后溢出),則要將乘2后的值異或{1b},二進制形式為{00011011};
- GF( 2 8 2^8 28)域中的乘法運算滿足分配律,例如:
07 · S 0 , 0 = ( 01 ⊕ 02 ⊕ 04 ) S 0 , 0 = S 0 , 0 ⊕ ( 02 · S 0 , 0 ) ⊕ ( 04 · S 0 , 0 ) 07·S_0,_0=(01⊕02⊕04)S_0,_0=S_0,_0⊕(02·S_0,_0)⊕(04·S_0,_0) 07·S0?,0?=(01⊕02⊕04)S0?,0?=S0?,0?⊕(02·S0?,0?)⊕(04·S0?,0?)
輪密鑰加(AddRoundKey)的計算原理相對簡單,將輸入狀態(tài)矩陣中對應(yīng)的元素與輸入的密鑰或者擴展后的密鑰相異或。
密鑰擴展(KeyExpansion)是用輸入的128位(AES-128)密鑰做為初始密鑰,使用特定的計算方法產(chǎn)生新的擴展密鑰的操作。
對AES-128來說,密鑰擴展共有10輪,每一輪產(chǎn)生4個32bits的子密鑰,一共產(chǎn)生10×4×32bits的子密鑰。
上圖(a)中,k矩陣為輸入的128bits初始密鑰,按每列4個字節(jié)的方式分為4個32bits的字,將這4個初始密鑰組合成的字 w 1 w_1 w1?, w 2 w_2 w2?, w 3 w_3 w3?, w 4 w_4 w4?作為加密時第一次輪密鑰加的輪密鑰。然后依次以下面的方法求出 w j w_j wj?。
- 若j不為4的整數(shù)倍,則 w j w_j wj?由下式確定:
w j = w j ? 4 ⊕ w j ? 1 w_j=w_j-_4⊕w_j-_1 wj?=wj??4?⊕wj??1?- 若j為4的整數(shù)倍,則 w j w_j wj?由下式確定:
w j = w j ? 4 ⊕ g ( w j ? 1 ) w_j=w_j-_4⊕g(w_j-_1) wj?=wj??4?⊕g(wj??1?)
g ( w ) g(w) g(w)函數(shù)如(b)所示,操作如下:
- 首先將w中的元素循環(huán)左移1 byte,
- 每個元素在S-Box進行替換
- 與32bits常量{RC[j/4],00,00,00}異或,其中RC是一個固定的一維數(shù)組,RC值如下:RC={00,01,02,04,08,10,20,40,80,1B,36}
ps:原本的RC值有10個(沒有RC[0]即00),而此處加上00是為了公式中表示數(shù)組時的便利。在g函數(shù)的運算過程中,由于j的值最小為4,j/4的值最小為1,所以不會產(chǎn)生影響。
現(xiàn)在加密輪函數(shù)和密鑰擴展都已經(jīng)知道了,那按照加密流程中一步步計算,即可得到加密后的密文。
由于篇幅原因,本文只對加密原理進行講解,解密原理即逆運算原理如有需要會在后續(xù)更新,可關(guān)注后續(xù)文章。
matlab驗證結(jié)果。(源碼獲取關(guān)注公眾號【兩猿社】,回復(fù)【AES】)
本設(shè)計為AES-128bits,輸入的128bits明文和初始密鑰,對明文(密文)進行十輪加解密之后輸出密文(明文)。
該設(shè)計包含數(shù)據(jù)收發(fā)模塊、Sbox和Inv_Sbox模塊、密鑰擴展模塊以及加解密模塊。其中在加密模式下,由于每字節(jié)明文對應(yīng)一個Sbox,則加密時需要16個Sbox(密鑰擴展在開始加密前就已經(jīng)完成,所用的4個Sbox可復(fù)用),解密模式下需要16個Inv_Sbox和4個Sbox(密鑰擴展)。
考慮到AES-128模式下密鑰及明文或密文的寬度都是128bits,如果使用FPGA直接綜合,輸入和輸出至少需要384個IO口,因此為了節(jié)約IO口,本設(shè)計使用32bits寬度進行數(shù)據(jù)的傳輸。
Testbench結(jié)構(gòu)包括發(fā)送模型send_model,接收模型receive_model,仿真模型即參考模型refer_model和自動對比模型auto_com。
呼,終于完了,現(xiàn)在你了解AES加密了嗎?
關(guān)注公眾號【兩猿社】,微信號 : twomonkeysclub
回復(fù)【AES】獲取Matlab和Veriolg源碼。
在這里,我會分享互聯(lián)網(wǎng)、IC編程知識,以及一些有趣的想法和經(jīng)歷。
聯(lián)系客服