AESEncryption.cs
public class AESEncryption
{
private static byte[] _key1 = {
0x36,
0x64,
0x9A,
0xF2,
0x6D,
0xDE,
0x0C,
0x3A,
0x0F,
0x1E,
0x2D,
0x3C,
0x4B,
0x5A,
0x69,
0x78 };
public static byte[]
AESEncrypt(
byte[] inputByteArray)
{
SymmetricAlgorithm des = Rijndael.Create();
des.Key = _key1;
des.IV = _key1;
MemoryStream ms =
new MemoryStream();
CryptoStream cs =
new CryptoStream(ms, des.CreateEncryptor(), CryptoStreamMode.Write);
cs.Write(inputByteArray,
0, inputByteArray.Length);
cs.FlushFinalBlock();
byte[] cipherBytes = ms.ToArray();
cs.Close();
ms.Close();
return cipherBytes;
}
public static byte[]
AESDecrypt(
byte[] cipherText)
{
SymmetricAlgorithm des = Rijndael.Create();
des.Key = _key1;
des.IV = _key1;
byte[] decryptBytes =
new byte[cipherText.Length];
MemoryStream ms =
new MemoryStream(cipherText);
CryptoStream cs =
new CryptoStream(ms, des.CreateDecryptor(), CryptoStreamMode.Read);
cs.Read(decryptBytes,
0, decryptBytes.Length);
cs.Close();
ms.Close();
return decryptBytes;
}
}
Aes.cs
public class Aes // 高级加密标准
{
public enum KeySize
{
Bits128,
Bits192,
Bits256
};
private readonly byte[] key;
private byte[,] Dbox;
private int Nb;
private int Nk;
private int Nr;
private byte[,] Rcon;
private byte[,] Sbox;
private char Source;
private byte[,] State;
private byte[,] iDbox;
private byte[,] iSbox;
private bool mode =
true;
private int round;
private byte size;
private byte[,] w;
public Aes(KeySize keySize,
byte[] keyBytes)
{
SetNbNkNr(keySize);
key =
new byte[Nk*
4];
keyBytes.CopyTo(key,
0);
BuildSbox();
BuildInvSbox();
InitdBox();
BuildRcon();
KeyExpansion();
}
private void InitdBox()
{
Dbox =
new byte[
16,
16];
iDbox =
new byte[
16,
16];
}
private void BuildDbox(
byte[,] statebox,
int round)
{
var Temp =
new byte[
16];
BuildLCS(
ref Temp, round);
byte AddByte =
0, t =
0;
for (
byte k =
0; k <
16; k +=
2)
{
AddByte <<=
1;
t = (
byte) (Temp[k] &
0x01);
AddByte |= t;
}
for (
byte i =
0; i <
16; i++)
{
for (
byte r =
0; r <
4; ++r)
for (
byte c =
0; c <
4; Temp[r*
4 + c] = w[((Nr - round)*
4) + c, r], ++c) ;
for (
byte j =
0; j <
16; j++)
{
byte row, col, y =
0;
Dbox[i, j] = (
byte) (statebox[i, j] ^ AddByte);
row = (
byte) (Dbox[i, j] >>
4);
col = (
byte) (Dbox[i, j] &
0x0f);
iDbox[row, col] = (
byte) (i <<
4 | j);
}
}
}
private void BuildLCS(
ref byte[] Data,
int times)
{
for (
int i =
0; i < times; i++)
{
byte temp = Data[
0];
for (
int j =
0; j <
15; Data[j] = Data[j +
1], j++) ;
Data[
15] = temp;
}
}
public void Cipher(
byte[] input,
byte[] output) // 加密16位输入
{
State =
new byte[
4, Nb];
for (
int i =
0; i < (
4*Nb); ++i)
{
State[i %
4, i /
4] = input[i];
}
AddRoundKey(
0);
int round;
for (round =
1; round <= (Nr -
1); ++round)
{
SubBytes(round);
ShiftRows();
MixColumns();
AddRoundKey(round);
}
SubBytes(Nr);
ShiftRows();
AddRoundKey(Nr);
for (
int i =
0; i < (
4*Nb); ++i)
{
output[i] = State[i%
4, i/
4];
}
}
public void InvCipher(
byte[] input,
byte[] output) // 解密16位输入
{
State =
new byte[
4, Nb];
for (
int i =
0; i < (
4*Nb); ++i)
{
State[i%
4, i/
4] = input[i];
}
AddRoundKey(Nr);
for (
int round = Nr -
1; round >=
1; --round)
{
InvShiftRows();
InvSubBytes(round +
1);
AddRoundKey(round);
InvMixColumns();
}
InvShiftRows();
InvSubBytes(
1);
AddRoundKey(
0);
for (
int i =
0; i < (
4*Nb); ++i)
{
output[i] = State[i%
4, i/
4];
}
}
private void SetNbNkNr(KeySize keySize)
{
Nb =
4;
if (keySize == KeySize.Bits128)
{
Nk =
4;
Nr =
10;
}
else if (keySize == KeySize.Bits192)
{
Nk =
6;
Nr =
12;
}
else if (keySize == KeySize.Bits256)
{
Nk =
8;
Nr =
14;
}
}
private void BuildSbox()
{
Sbox =
new byte[
16,
16]
{
{
0x63,
0x7c,
0x77,
0x7b,
0xf2,
0x6b,
0x6f,
0xc5,
0x30,
0x01,
0x67,
0x2b,
0xfe,
0xd7,
0xab,
0x76},
{
0xca,
0x82,
0xc9,
0x7d,
0xfa,
0x59,
0x47,
0xf0,
0xad,
0xd4,
0xa2,
0xaf,
0x9c,
0xa4,
0x72,
0xc0},
{
0xb7,
0xfd,
0x93,
0x26,
0x36,
0x3f,
0xf7,
0xcc,
0x34,
0xa5,
0xe5,
0xf1,
0x71,
0xd8,
0x31,
0x15},
{
0x04,
0xc7,
0x23,
0xc3,
0x18,
0x96,
0x05,
0x9a,
0x07,
0x12,
0x80,
0xe2,
0xeb,
0x27,
0xb2,
0x75},
{
0x09,
0x83,
0x2c,
0x1a,
0x1b,
0x6e,
0x5a,
0xa0,
0x52,
0x3b,
0xd6,
0xb3,
0x29,
0xe3,
0x2f,
0x84},
{
0x53,
0xd1,
0x00,
0xed,
0x20,
0xfc,
0xb1,
0x5b,
0x6a,
0xcb,
0xbe,
0x39,
0x4a,
0x4c,
0x58,
0xcf},
{
0xd0,
0xef,
0xaa,
0xfb,
0x43,
0x4d,
0x33,
0x85,
0x45,
0xf9,
0x02,
0x7f,
0x50,
0x3c,
0x9f,
0xa8},
{
0x51,
0xa3,
0x40,
0x8f,
0x92,
0x9d,
0x38,
0xf5,
0xbc,
0xb6,
0xda,
0x21,
0x10,
0xff,
0xf3,
0xd2},
{
0xcd,
0x0c,
0x13,
0xec,
0x5f,
0x97,
0x44,
0x17,
0xc4,
0xa7,
0x7e,
0x3d,
0x64,
0x5d,
0x19,
0x73},
{
0x60,
0x81,
0x4f,
0xdc,
0x22,
0x2a,
0x90,
0x88,
0x46,
0xee,
0xb8,
0x14,
0xde,
0x5e,
0x0b,
0xdb},
{
0xe0,
0x32,
0x3a,
0x0a,
0x49,
0x06,
0x24,
0x5c,
0xc2,
0xd3,
0xac,
0x62,
0x91,
0x95,
0xe4,
0x79},
{
0xe7,
0xc8,
0x37,
0x6d,
0x8d,
0xd5,
0x4e,
0xa9,
0x6c,
0x56,
0xf4,
0xea,
0x65,
0x7a,
0xae,
0x08},
{
0xba,
0x78,
0x25,
0x2e,
0x1c,
0xa6,
0xb4,
0xc6,
0xe8,
0xdd,
0x74,
0x1f,
0x4b,
0xbd,
0x8b,
0x8a},
{
0x70,
0x3e,
0xb5,
0x66,
0x48,
0x03,
0xf6,
0x0e,
0x61,
0x35,
0x57,
0xb9,
0x86,
0xc1,
0x1d,
0x9e},
{
0xe1,
0xf8,
0x98,
0x11,
0x69,
0xd9,
0x8e,
0x94,
0x9b,
0x1e,
0x87,
0xe9,
0xce,
0x55,
0x28,
0xdf},
{
0x8c,
0xa1,
0x89,
0x0d,
0xbf,
0xe6,
0x42,
0x68,
0x41,
0x99,
0x2d,
0x0f,
0xb0,
0x54,
0xbb,
0x16}
};
}
private void BuildInvSbox()
{
iSbox =
new byte[
16,
16]
{
{
0x52,
0x09,
0x6a,
0xd5,
0x30,
0x36,
0xa5,
0x38,
0xbf,
0x40,
0xa3,
0x9e,
0x81,
0xf3,
0xd7,
0xfb},
{
0x7c,
0xe3,
0x39,
0x82,
0x9b,
0x2f,
0xff,
0x87,
0x34,
0x8e,
0x43,
0x44,
0xc4,
0xde,
0xe9,
0xcb},
{
0x54,
0x7b,
0x94,
0x32,
0xa6,
0xc2,
0x23,
0x3d,
0xee,
0x4c,
0x95,
0x0b,
0x42,
0xfa,
0xc3,
0x4e},
{
0x08,
0x2e,
0xa1,
0x66,
0x28,
0xd9,
0x24,
0xb2,
0x76,
0x5b,
0xa2,
0x49,
0x6d,
0x8b,
0xd1,
0x25},
{
0x72,
0xf8,
0xf6,
0x64,
0x86,
0x68,
0x98,
0x16,
0xd4,
0xa4,
0x5c,
0xcc,
0x5d,
0x65,
0xb6,
0x92},
{
0x6c,
0x70,
0x48,
0x50,
0xfd,
0xed,
0xb9,
0xda,
0x5e,
0x15,
0x46,
0x57,
0xa7,
0x8d,
0x9d,
0x84},
{
0x90,
0xd8,
0xab,
0x00,
0x8c,
0xbc,
0xd3,
0x0a,
0xf7,
0xe4,
0x58,
0x05,
0xb8,
0xb3,
0x45,
0x06},
{
0xd0,
0x2c,
0x1e,
0x8f,
0xca,
0x3f,
0x0f,
0x02,
0xc1,
0xaf,
0xbd,
0x03,
0x01,
0x13,
0x8a,
0x6b},
{
0x3a,
0x91,
0x11,
0x41,
0x4f,
0x67,
0xdc,
0xea,
0x97,
0xf2,
0xcf,
0xce,
0xf0,
0xb4,
0xe6,
0x73},
{
0x96,
0xac,
0x74,
0x22,
0xe7,
0xad,
0x35,
0x85,
0xe2,
0xf9,
0x37,
0xe8,
0x1c,
0x75,
0xdf,
0x6e},
{
0x47,
0xf1,
0x1a,
0x71,
0x1d,
0x29,
0xc5,
0x89,
0x6f,
0xb7,
0x62,
0x0e,
0xaa,
0x18,
0xbe,
0x1b},
{
0xfc,
0x56,
0x3e,
0x4b,
0xc6,
0xd2,
0x79,
0x20,
0x9a,
0xdb,
0xc0,
0xfe,
0x78,
0xcd,
0x5a,
0xf4},
{
0x1f,
0xdd,
0xa8,
0x33,
0x88,
0x07,
0xc7,
0x31,
0xb1,
0x12,
0x10,
0x59,
0x27,
0x80,
0xec,
0x5f},
{
0x60,
0x51,
0x7f,
0xa9,
0x19,
0xb5,
0x4a,
0x0d,
0x2d,
0xe5,
0x7a,
0x9f,
0x93,
0xc9,
0x9c,
0xef},
{
0xa0,
0xe0,
0x3b,
0x4d,
0xae,
0x2a,
0xf5,
0xb0,
0xc8,
0xeb,
0xbb,
0x3c,
0x83,
0x53,
0x99,
0x61},
{
0x17,
0x2b,
0x04,
0x7e,
0xba,
0x77,
0xd6,
0x26,
0xe1,
0x69,
0x14,
0x63,
0x55,
0x21,
0x0c,
0x7d}
};
}
private void BuildRcon()
{
Rcon =
new byte[
11,
4]
{
{
0x00,
0x00,
0x00,
0x00},
{
0x01,
0x00,
0x00,
0x00},
{
0x02,
0x00,
0x00,
0x00},
{
0x04,
0x00,
0x00,
0x00},
{
0x08,
0x00,
0x00,
0x00},
{
0x10,
0x00,
0x00,
0x00},
{
0x20,
0x00,
0x00,
0x00},
{
0x40,
0x00,
0x00,
0x00},
{
0x80,
0x00,
0x00,
0x00},
{
0x1b,
0x00,
0x00,
0x00},
{
0x36,
0x00,
0x00,
0x00}
};
}
private void AddRoundKey(
int round)
{
for (
int r =
0; r <
4; ++r)
{
for (
int c =
0; c <
4; ++c)
{
State[r, c] = (
byte) (State[r, c] ^ w[(round*
4) + c, r]);
}
}
}
private void SubBytes(
int round)
{
if (mode)
BuildDbox(Sbox, round);
for (
int r =
0; r <
4; ++r)
{
for (
int c =
0; c <
4; ++c)
{
if (mode)
State[r, c] = Dbox[(State[r, c] >>
4), (State[r, c] &
0x0f)];
else
State[r, c] = Sbox[(State[r, c] >>
4), (State[r, c] &
0x0f)];
}
}
}
private void InvSubBytes(
int round)
{
if (mode)
BuildDbox(Sbox, round);
for (
int r =
0; r <
4; ++r)
{
for (
int c =
0; c <
4; ++c)
{
if (mode)
State[r, c] = iDbox[(State[r, c] >>
4), (State[r, c] &
0x0f)];
else
State[r, c] = iSbox[(State[r, c] >>
4), (State[r, c] &
0x0f)];
}
}
}
private void ShiftRows()
{
var temp =
new byte[
4,
4];
for (
int r =
0; r <
4; ++r)
{
for (
int c =
0; c <
4; ++c)
{
temp[r, c] = State[r, c];
}
}
for (
int r =
1; r <
4; ++r)
{
for (
int c =
0; c <
4; ++c)
{
State[r, c] = temp[r, (c + r)%Nb];
}
}
}
private void InvShiftRows()
{
var temp =
new byte[
4,
4];
for (
int r =
0; r <
4; ++r)
{
for (
int c =
0; c <
4; ++c)
{
temp[r, c] = State[r, c];
}
}
for (
int r =
1; r <
4; ++r)
{
for (
int c =
0; c <
4; ++c)
{
State[r, (c + r)%Nb] = temp[r, c];
}
}
}
private void MixColumns()
{
var temp =
new byte[
4,
4];
for (
int r =
0; r <
4; ++r)
{
for (
int c =
0; c <
4; ++c)
{
temp[r, c] = State[r, c];
}
}
for (
int c =
0; c <
4; ++c)
{
State[
0, c] = (
byte) (gfmultby02(temp[
0, c]) ^ gfmultby03(temp[
1, c]) ^
gfmultby01(temp[
2, c]) ^ gfmultby01(temp[
3, c]));
State[
1, c] = (
byte) (gfmultby01(temp[
0, c]) ^ gfmultby02(temp[
1, c]) ^
gfmultby03(temp[
2, c]) ^ gfmultby01(temp[
3, c]));
State[
2, c] = (
byte) (gfmultby01(temp[
0, c]) ^ gfmultby01(temp[
1, c]) ^
gfmultby02(temp[
2, c]) ^ gfmultby03(temp[
3, c]));
State[
3, c] = (
byte) (gfmultby03(temp[
0, c]) ^ gfmultby01(temp[
1, c]) ^
gfmultby01(temp[
2, c]) ^ gfmultby02(temp[
3, c]));
}
}
private void InvMixColumns()
{
var temp =
new byte[
4,
4];
for (
int r =
0; r <
4; ++r)
{
for (
int c =
0; c <
4; ++c)
{
temp[r, c] = State[r, c];
}
}
for (
int c =
0; c <
4; ++c)
{
State[
0, c] = (
byte) (gfmultby0e(temp[
0, c]) ^ gfmultby0b(temp[
1, c]) ^
gfmultby0d(temp[
2, c]) ^ gfmultby09(temp[
3, c]));
State[
1, c] = (
byte) (gfmultby09(temp[
0, c]) ^ gfmultby0e(temp[
1, c]) ^
gfmultby0b(temp[
2, c]) ^ gfmultby0d(temp[
3, c]));
State[
2, c] = (
byte) (gfmultby0d(temp[
0, c]) ^ gfmultby09(temp[
1, c]) ^
gfmultby0e(temp[
2, c]) ^ gfmultby0b(temp[
3, c]));
State[
3, c] = (
byte) (gfmultby0b(temp[
0, c]) ^ gfmultby0d(temp[
1, c]) ^
gfmultby09(temp[
2, c]) ^ gfmultby0e(temp[
3, c]));
}
}
private static byte gfmultby01(
byte b)
{
return b;
}
private static byte gfmultby02(
byte b)
{
if (b <
0x80)
return (
byte) (b <<
1);
return (
byte) (b <<
1 ^
0x1b);
}
private static byte gfmultby03(
byte b)
{
return (
byte) (gfmultby02(b) ^ b);
}
private static byte gfmultby09(
byte b)
{
return (
byte) (gfmultby02(gfmultby02(gfmultby02(b))) ^
b);
}
private static byte gfmultby0b(
byte b)
{
return (
byte) (gfmultby02(gfmultby02(gfmultby02(b))) ^
gfmultby02(b) ^
b);
}
private static byte gfmultby0d(
byte b)
{
return (
byte) (gfmultby02(gfmultby02(gfmultby02(b))) ^
gfmultby02(gfmultby02(b)) ^
b);
}
private static byte gfmultby0e(
byte b)
{
return (
byte) (gfmultby02(gfmultby02(gfmultby02(b))) ^
gfmultby02(gfmultby02(b)) ^
gfmultby02(b));
}
private void KeyExpansion()
{
w =
new byte[Nb*(Nr +
1),
4];
for (
int row =
0; row < Nk; ++row)
{
w[row,
0] = key[
4*row];
w[row,
1] = key[
4*row +
1];
w[row,
2] = key[
4*row +
2];
w[row,
3] = key[
4*row +
3];
}
var temp =
new byte[
4];
for (
int row = Nk; row < Nb*(Nr +
1); ++row)
{
temp[
0] = w[row -
1,
0];
temp[
1] = w[row -
1,
1];
temp[
2] = w[row -
1,
2];
temp[
3] = w[row -
1,
3];
if (row % Nk ==
0)
{
temp = SubWord(RotWord(temp));
temp[
0] = (
byte) (temp[
0] ^ Rcon[row/Nk,
0]);
temp[
1] = (
byte) (temp[
1] ^ Rcon[row/Nk,
1]);
temp[
2] = (
byte) (temp[
2] ^ Rcon[row/Nk,
2]);
temp[
3] = (
byte) (temp[
3] ^ Rcon[row/Nk,
3]);
}
else if (Nk >
6 && (row%Nk ==
4))
{
temp = SubWord(temp);
}
w[row,
0] = (
byte) (w[row - Nk,
0] ^ temp[
0]);
w[row,
1] = (
byte) (w[row - Nk,
1] ^ temp[
1]);
w[row,
2] = (
byte) (w[row - Nk,
2] ^ temp[
2]);
w[row,
3] = (
byte) (w[row - Nk,
3] ^ temp[
3]);
}
}
private byte[]
SubWord(
byte[] word)
{
var result =
new byte[
4];
result[
0] = Sbox[word[
0] >>
4, word[
0] &
0x0f];
result[
1] = Sbox[word[
1] >>
4, word[
1] &
0x0f];
result[
2] = Sbox[word[
2] >>
4, word[
2] &
0x0f];
result[
3] = Sbox[word[
3] >>
4, word[
3] &
0x0f];
return result;
}
private byte[]
RotWord(
byte[] word)
{
var result =
new byte[
4];
result[
0] = word[
1];
result[
1] = word[
2];
result[
2] = word[
3];
result[
3] = word[
0];
return result;
}
public void Dump()
{
Console.WriteLine(
"Nb = " + Nb +
" Nk = " + Nk +
" Nr = " + Nr);
Console.WriteLine(
"\nThe key is \n" + DumpKey());
Console.WriteLine(
"\nThe Sbox is \n" + DumpTwoByTwo(Sbox));
Console.WriteLine(
"\nThe w array is \n" + DumpTwoByTwo(w));
Console.WriteLine(
"\nThe State array is \n" + DumpTwoByTwo(State));
}
public string DumpKey()
{
string s =
"";
for (
int i =
0; i < key.Length; ++i)
s += key[i].ToString(
"x2") +
" ";
return s;
}
public string DumpTwoByTwo(
byte[,] a)
{
string s =
"";
for (
int r =
0; r < a.GetLength(
0); ++r)
{
s +=
"[" + r +
"]" +
" ";
for (
int c =
0; c < a.GetLength(
1); ++c)
{
s += a[r, c].ToString(
"x2") +
" ";
}
s +=
"\n";
}
return s;
}
}
Program.cs
class Program
{
private static void pause()
{
Console.Write(
"按任意键继续 . . . ");
Console.ReadKey(
true);
}
public static string ToHexString(
byte[] bytes, String flag =
",")
{
string hexString =
string.Empty;
if (bytes !=
null)
{
var strB =
new StringBuilder();
for (
int i =
0; i < bytes.Length; i++)
{
strB.Append(bytes[i].ToString(
"X2"));
strB.Append(flag);
}
hexString = strB.ToString();
}
return hexString;
}
private static void Main(
string[] args)
{
byte[] inputByteArrayOne =
{
0xAA,
0x55,
0xBB,
0x66,
0x00,
0x02,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00
};
byte[] outputByteArrayOne = AESEncryption.AESEncrypt(inputByteArrayOne);
byte[] outputByteArrayTwo = AESEncryption.AESDecrypt(outputByteArrayOne);
Console.WriteLine(
"输入值 - " + ToHexString(outputByteArrayTwo));
Console.WriteLine(
"输出值 - " + ToHexString(outputByteArrayOne));
Console.WriteLine();
Aes.KeySize keysize;
keysize = Aes.KeySize.Bits128;
byte[] inputByteArray =
{
0xAA,
0x55,
0xBB,
0x66,
0x00,
0x02,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00
};
byte[] _key1 =
{
0x36,
0x64,
0x9A,
0xF2,
0x6D,
0xDE,
0x0C,
0x3A,
0x0F,
0x1E,
0x2D,
0x3C,
0x4B,
0x5A,
0x69,
0x78
};
var a =
new Aes(keysize, _key1);
var outputByteArray =
new byte[
16];
a.Cipher(inputByteArray, outputByteArray);
var outputByteArray1 =
new byte[
16];
a.InvCipher(outputByteArray, outputByteArray1);
string hex2 = ToHexString(outputByteArray);
string hex1 = ToHexString(outputByteArray1);
Console.WriteLine(
"输入值 - " + hex1);
Console.WriteLine(
"输出值 - " + hex2);
pause();
}
}
运行结果如图: