AES 是?Advanced Encryption Standard 的縮寫(xiě),是最常見(jiàn)的對(duì)稱加密算法。AES 在密碼學(xué)中又稱 Rijndael 加密法,是美國(guó)聯(lián)邦政府采用的一種區(qū)塊加密標(biāo)準(zhǔn)。這個(gè)標(biāo)準(zhǔn)用來(lái)替代原先的 DES,已經(jīng)被多方分析且廣為全世界所使用。
AES基本原理
AES 的加密公式為 C=E(K,P),其中 K 為密鑰,P 為明文,C 為密文。
AES 加密明文的過(guò)程是,首先對(duì)明文進(jìn)行分組,每組的長(zhǎng)度都是 128 位,然后一組一組地加密,直到所有明文都已加密。密鑰的長(zhǎng)度可以是 128、192 或 256 位。
在加密函數(shù) E 中,會(huì)執(zhí)行一個(gè)輪函數(shù),除最后一次執(zhí)行不同外,前面幾輪的執(zhí)行是相同的。以 AES-128 為例,推薦加密輪數(shù)為 10 輪,即前 9 輪執(zhí)行的操作相同,第 10 輪執(zhí)行的操作與前面不同。不同的密鑰長(zhǎng)度推薦的加密輪數(shù)是不一樣的,具體見(jiàn)下面的表格。
加密時(shí),明文按照 128 位為單位進(jìn)行分組,每組包含?16 個(gè)字節(jié),按照從上到下、從左到右的順序排列成一個(gè) 4 × 4 的矩陣,稱為明文矩陣。AES 的加密過(guò)程在一個(gè)大小同樣為 4 × 4 的矩陣中進(jìn)行,稱為狀態(tài)矩陣,狀態(tài)矩陣的初始值為明文矩陣的值。每一輪加密結(jié)束后,狀態(tài)矩陣的值變化一次。輪函數(shù)執(zhí)行結(jié)束后,狀態(tài)矩陣的值即為密文的值,從狀態(tài)矩陣得到密文矩陣,依次提取密文矩陣的值得到 128 位的密文。
以 128 位密鑰為例,密鑰長(zhǎng)度為 16 個(gè)字節(jié),也用 4 × 4 的矩陣表示,順序也是從上到下、從左到右。AES 通過(guò)密鑰編排函數(shù)把密鑰矩陣擴(kuò)展成一個(gè)包含 44 個(gè)字的密鑰序列,其中的前 4 個(gè)字為原始密鑰用于初始加密,后面的 40 個(gè)字用于 10 輪加密,每輪使用其中的 4 個(gè)字。密鑰遞歸產(chǎn)生規(guī)則如下:
(1) 如果 i 不是 4 的倍數(shù),那么由等式 w[i] = w[i-4] ⊕ w[i-1] 確定;
(2) 如果 i 是 4 的倍數(shù),那么由等式 w[i] = w[i-4] ⊕ T(w[i-1]) 確定。
加密的第 1 輪到第 9 輪的輪函數(shù)一樣,包括 4 個(gè)操作:字節(jié)代換、行位移、列混合和輪密鑰加。最后一輪迭代不執(zhí)行列混合。另外,在第一輪迭代之前,先將明文和原始密鑰進(jìn)行一次異或加密操作。?
AES 加密的輪函數(shù)操作
字節(jié)代換 SubBytes
矩陣中的各字節(jié)通過(guò)一個(gè) 8 位的 S-box 進(jìn)行轉(zhuǎn)換。這個(gè)步驟提供了加密法非線性的變換能力。S-box 與 GF(2^8)上的乘法反元素有關(guān),已知具有良好的非線性特性。為了避免簡(jiǎn)單代數(shù)性質(zhì)的攻擊,S-box 結(jié)合了乘法反元素及一個(gè)可逆的仿射變換矩陣建構(gòu)而成。此外在建構(gòu) S-box 時(shí),刻意避開(kāi)了固定點(diǎn)與反固定點(diǎn),即以 S-box 替換字節(jié)的結(jié)果會(huì)相當(dāng)于錯(cuò)排的結(jié)果。
行位移?ShiftRows
在此步驟中,每一行都向左循環(huán)位移某個(gè)偏移量。在 AES 中(區(qū)塊大小 128位 ),第一行維持不變,第二行里的每個(gè)字節(jié)都向左循環(huán)移動(dòng)一格。同理,第三行及第四行向左循環(huán)位移的偏移量就分別是 2 和 3。128 位和 192 位的區(qū)塊在此步驟的循環(huán)位移的模式相同。經(jīng)過(guò) ShiftRows 之后,矩陣中每一豎列,都是由輸入矩陣中的每個(gè)不同列中的元素組成。Rijndael 算法的版本中,偏移量和 AES 有少許不同;對(duì)于長(zhǎng)度 256 比特的區(qū)塊,第一行仍然維持不變,第二行、第三行、第四行的偏移量分別是 1 字節(jié)、2 字節(jié)、3 字節(jié)。除此之外,ShiftRows 操作步驟在 Rijndael 和 AES 中完全相同。
列混合?MixColumns
在 MixColumns 步驟,每一列的四個(gè)字節(jié)通過(guò)線性變換互相結(jié)合。每一列的四個(gè)元素分別當(dāng)作 1 , x , x^2 , x^3 的系數(shù),合并即為GF(2^8)中的一個(gè)多項(xiàng)式,接著將此多項(xiàng)式和一個(gè)固定的多項(xiàng)式 c(x)=3x^3+x^2+x+2 在 modulo x^4 + 1 下相乘。此步驟亦可視為 Rijndael 有限域之下的矩陣乘法。MixColumns 函數(shù)接受 4 個(gè)字節(jié)的輸入,輸出 4 個(gè)字節(jié),每一個(gè)輸入的字節(jié)都會(huì)對(duì)輸出的四個(gè)字節(jié)造成影響。因此 ShiftRows 和 MixColumns 兩步驟為這個(gè)密碼系統(tǒng)提供了擴(kuò)散性。
輪密鑰加 AddRoundKey
回合密鑰將會(huì)與原矩陣合并。在每次的加密循環(huán)中,都會(huì)由主密鑰產(chǎn)生一把回合密鑰(通過(guò) Rijndael 密鑰生成方案產(chǎn)生),這把密鑰大小會(huì)跟原矩陣一樣,以與原矩陣中每個(gè)對(duì)應(yīng)的字節(jié)作異或(⊕)加法。
分享學(xué)習(xí)筆記和技術(shù)總結(jié),內(nèi)容涉及 Java 進(jìn)階、架構(gòu)設(shè)計(jì)、前沿技術(shù)、算法與數(shù)據(jù)結(jié)構(gòu)、數(shù)據(jù)庫(kù)、中間件等多個(gè)領(lǐng)域,歡迎關(guān)注。本文首發(fā)于微信公眾號(hào)“后端開(kāi)發(fā)那點(diǎn)事兒”。