一、所謂AES加密:
二、中間怎么變換的呢?128位加密為例:
AES算法,基本變換包括SubBytes(字節替代)、ShiftRows(行移位)、MixColumns(列混淆)、AddRoundKey(輪密鑰加)。
加密過程可參見:http://coolshell.cn/wp-content/uploads/2010/10/rijndael_ingles2004.swf
然后我會以這個視頻動畫為基礎,加以說明:
1)左邊是需要加密的,右邊是密鑰:
2)SubBytes(字節替代)過程:
這一步可以直接查表:如19就對應着0xd4;a0對應0xe0;...
unsigned
char
sBox[] =
{
/* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
0x63,0x7c,0x77,0x7b,0xf2,0x6b,0x6f,0xc5,0x30,0x01,0x67,0x2b,0xfe,0xd7,0xab,0x76,
/*0*/
0xca,0x82,0xc9,0x7d,0xfa,0x59,0x47,0xf0,0xad,0xd4,0xa2,0xaf,0x9c,0xa4,0x72,0xc0,
/*1*/
0xb7,0xfd,0x93,0x26,0x36,0x3f,0xf7,0xcc,0x34,0xa5,0xe5,0xf1,0x71,0xd8,0x31,0x15,
/*2*/
0x04,0xc7,0x23,0xc3,0x18,0x96,0x05,0x9a,0x07,0x12,0x80,0xe2,0xeb,0x27,0xb2,0x75,
/*3*/
0x09,0x83,0x2c,0x1a,0x1b,0x6e,0x5a,0xa0,0x52,0x3b,0xd6,0xb3,0x29,0xe3,0x2f,0x84,
/*4*/
0x53,0xd1,0x00,0xed,0x20,0xfc,0xb1,0x5b,0x6a,0xcb,0xbe,0x39,0x4a,0x4c,0x58,0xcf,
/*5*/
0xd0,0xef,0xaa,0xfb,0x43,0x4d,0x33,0x85,0x45,0xf9,0x02,0x7f,0x50,0x3c,0x9f,0xa8,
/*6*/
0x51,0xa3,0x40,0x8f,0x92,0x9d,0x38,0xf5,0xbc,0xb6,0xda,0x21,0x10,0xff,0xf3,0xd2,
/*7*/
0xcd,0x0c,0x13,0xec,0x5f,0x97,0x44,0x17,0xc4,0xa7,0x7e,0x3d,0x64,0x5d,0x19,0x73,
/*8*/
0x60,0x81,0x4f,0xdc,0x22,0x2a,0x90,0x88,0x46,0xee,0xb8,0x14,0xde,0x5e,0x0b,0xdb,
/*9*/
0xe0,0x32,0x3a,0x0a,0x49,0x06,0x24,0x5c,0xc2,0xd3,0xac,0x62,0x91,0x95,0xe4,0x79,
/*a*/
0xe7,0xc8,0x37,0x6d,0x8d,0xd5,0x4e,0xa9,0x6c,0x56,0xf4,0xea,0x65,0x7a,0xae,0x08,
/*b*/
0xba,0x78,0x25,0x2e,0x1c,0xa6,0xb4,0xc6,0xe8,0xdd,0x74,0x1f,0x4b,0xbd,0x8b,0x8a,
/*c*/
0x70,0x3e,0xb5,0x66,0x48,0x03,0xf6,0x0e,0x61,0x35,0x57,0xb9,0x86,0xc1,0x1d,0x9e,
/*d*/
0xe1,0xf8,0x98,0x11,0x69,0xd9,0x8e,0x94,0x9b,0x1e,0x87,0xe9,0xce,0x55,0x28,0xdf,
/*e*/
0x8c,0xa1,0x89,0x0d,0xbf,0xe6,0x42,0x68,0x41,0x99,0x2d,0x0f,0xb0,0x54,0xbb,0x16
/*f*/
};
3)ShiftRows(行移位),這里也截取網上的圖片來說明:

4)MixColumns(列混淆):

我第一次考到這里也沒立即明白是怎么算出來的,這里是:用 State 字節列的值進行數學域加和域乘的結果代替每個字節。
下面一段是截取前人成果:
AES 所用的加法和乘法是基於數學(譯者注:近世代數)的域論。尤其是 AES 基於有限域GF(28)。 GF(28)由一組從 0x00 到 0xff 的256個值組成,加上加法和乘法,因此是(28)。GF代表伽羅瓦域,以發明這一理論的數學家的名字命名。GF(28) 的一個特性是一個加法或乘法的操作的結果必須是在{0x00 ... 0xff}這組數中。雖然域論是相當深奧的,但GF(28)加法的最終結果卻很簡單。GF(28) 加法就是異或(XOR)操作。 然而,GF(28)的乘法有點繁難。正如你稍后將在 C# 實現中所看到的,AES的加密和解密例程需要知道怎樣只用七個常量 0x01、0x02、0x03、0x09、0x0b、0x0d 和 0x0e 來相乘。所以我不全面介紹GF(28)的乘法,而只是針對這七種特殊情況進行說明。 在GF(28)中用0x01的乘法是特殊的;它相當於普通算術中用1做乘法並且結果也同樣—任何值乘0x01等於其自身。 現在讓我們看看用0x02做乘法。和加法的情況相同,理論是深奧的,但最終結果十分簡單。只要被乘的值小於0x80,這時乘法的結果就是該值左移1比特位。如果被乘的值大於或等於0x80,這時乘法的結果就是左移1比特位再用值0x1b異或。它防止了“域溢出”並保持乘法的乘積在范圍以內。 一旦你在GF(28)中用0x02建立了加法和乘法,你就可以用任何常量去定義乘法。用0x03做乘法時,你可以將 0x03 分解為2的冪之和。為了用 0x03 乘以任意字節b, 因為 0x03 = 0x02 + 0x01,因此: b * 0x03 = b * (0x02 + 0x01) = (b * 0x02) + (b * 0x01) 這是可以行得通的,因為你知道如何用 0x02 和 0x01 相乘和相加,同哩,用0x0d去乘以任意字節b可以這樣做: b * 0x0d = b * (0x08 + 0x04 + 0x01) = (b * 0x08) + (b * 0x04) + (b * 0x01) = (b * 0x02 * 0x02 * 0x02) + (b * 0x02 * 0x02) + (b * 0x01) 在加解密算法中,AES MixColumns 例程的其它乘法遵循大體相同的模式,如下所示: b * 0x09 = b * (0x08 + 0x01) = (b * 0x02 * 0x02 * 0x02) + (b * 0x01) b * 0x0b = b * (0x08 + 0x02 + 0x01) = (b * 0x02 * 0x02 * 0x02) + (b * 0x02) + (b * 0x01) b * 0x0e = b * (0x08 + 0x04 + 0x02) = (b * 0x02 * 0x02 * 0x02) + (b * 0x02 * 0x02) + (b * 0x02) 總之,在GF(28)中,加法是異或操作。其乘法將分解成加法和用0x02做的乘法,而用0x02做的乘法是一個有條件的左移1比特位。AES規范中包括大量 有關GF(28)操作的附加信息。
這下來看左上方的04是怎么得來的:
0xd4*0x02 ⊕ 0xbf*0x03 ⊕ 0x5d*0x01 ⊕ 0x30 * 0x01
=0xd4*0x02 ⊕ xbf*0x02 ⊕ 0xbf*0x01 ⊕ 0x5d*0x01 ⊕ 0x30 * 0x01
=0xd4*0x02 ⊕ xbf*0x02 ⊕ 0xbf ⊕ 0x5d ⊕ 0x30 (注意這里的0xd4*02就是0xd4左移一位,然后異或0x1b (0001 1011)哦,加法就是求異或)
=1010 1000⊕0001 1011 ⊕ 0111 1110 ⊕0001 1011 ⊕ 1011 1111 ⊕ 0101 1101 ⊕ 00110000
0001 1011 0001 1011 0101 1101
=1011 0011 ⊕ 0110 0101 ⊕ 1110 0010 ⊕ 00110000
0110 0101
=1101 0110 ⊕ 1110 0010 ⊕ 00110000
=0011 0100 ⊕ 00110000
=0000 0100
=0x04
5) AddRoundKey(輪密鑰加):
該部分就是把上一步的結果和密鑰進行異或;
得到的結果作為初始值,重復以上操作9次。第10次的時候不執行MixColumns直接和密鑰求異或操作,得到的最終結果就是密文。
注意:這的每輪一圈,密鑰都要schedule一次(俗稱:KeyExpansion(密鑰擴展)),具體算法:
<1>第n組第i列 為 第n-1組第i列 與 第n組第i-1列之和(模2加法,1<= i <=3)
<2>對於每一組 第一列即i=0,有特殊的處理:
將前一列即第n-1組第3列的4個字節循環左移1個字節,
並對每個字節進行字節替代變換SubBytes
將第一行(即第一個字節)與輪常量rc[n]相加
最后再與前一組該列相加。
這里的rc[n]是個定值:
就此AES加密過程結束!
三、解密的基本運算
AES解密算法與加密不同,基本運算中除了AddRoundKey(輪密鑰加)不變外,其余的都需要進行逆變換,即
InvSubBytes(逆字節替代)、InvShiftRows(逆行移位)、InvMixColumns(逆列混淆)
非128位的文件如何加密,還有192 256位加密解密...