用 C# 編寫 AES 類構造函數
現在我已研究了構成 AES 加密算法的各個成分,我將用 C# 來實現它。官方的 AES 算法規范包含在聯邦信息處理標准出版物197 (Federal Information Processing Standards Publication 197)中。我決定盡可能貼切地以它作為我的實現的基礎,但是我很快發現這個規范更是一個理論文獻而非一個實現的向導。為了將這個官方規范作為資源來使用,我使用的變量名與標准出版物中所用的相同。(即便它們是那麼晦澀,如“Nr”和“W”)。
我的設計使用9個數據成員和一個枚舉類型,如下所示:
public enum KeySize { Bits128, Bits192, Bits256 };
private int Nb;
private int Nk;
private int Nr;
private byte[] key;
private byte[,] Sbox;
private byte[,] iSbox;
private byte[,] w;
private byte[,] Rcon;
private byte[,] State;
因為密鑰長度只能是128位、192位或256位比特,它是非常適於用枚舉類型:
public enum KeySize { Bits128, Bits192, Bits256 };
該規范文檔一般用字節作為基本儲存單元而不是用4字節的字作為兩個重要數據成員的長度。這兩個成員 Nb和Nk 代表 以字為單位的塊長以及以字為單位的密鑰長度。Nr代表輪數。塊長度總是16字節(或這說是 128 位,即為AES的 4個字),因此它可以被聲明為一個常量。密鑰長度 依照枚舉參數 KeySize的值被賦值為4、6 或 8。AES 算法強調通過大量輪數來增加加密數據的復雜性。輪數是10、12或14中的任意一個並且是基於密碼分析學理論的。它直接取決於密鑰長度。
當設計一個類接口時,我喜歡向後來做。我設想從應用程序中調用構造函數和方法。使用這個辦法,我決定象下面這樣來實例化一個 AES 對象:
Aes a = new Aes(the key size, the seed key)
我調用的加密和解密例程如下:
a.Cipher(plainText, cipherText);
a.InvCipher(cipherText, decipheredText);
我選擇少許笨拙的方法來命名 Cipher和InvCipher,因為它們是用在AES 規范文檔中的。這裡是 AES 類構造函數的代碼為:
public Aes(KeySize keySize, byte[] keyBytes)
{
SetNbNkNr(keySize);
this.key = new byte[this.Nk * 4];
keyBytes.CopyTo(this.key, 0);
BuildSbox();
BuildInvSbox();
BuildRcon();
KeyExpansion();
}