public static int[,] GetKeyExpansion(string str) { str = str.ToLower(); byte[] buf = Encoding.UTF8.GetBytes(str); StringBuilder s = new StringBuilder(128); int nb = 4; int nk = buf.Length / 4; int nr = 0; switch (nk) { case 4: nr = 10; break; case 6: nr = 12; break; case 8: nr = 14; break; } int[,] key = new int[nb * (nr + 1), nb]; int[,] cipherKey = new int[nr + 1, 16]; int[] temp = new int[4]; for (int i = 0; i < buf.Length; i++) { for (int j = 7; j >= 0; j--) { s = s.Append(buf[i] >> j & 1); } } for (int i = 0; i < nk; i++) { for (int j = 0; j < nb; j++) { key[i, j] = Convert.ToInt32(s.ToString(8 * j + i * 32, 8), 2); } } for (int i = nk; i < nb * (nr + 1); i++) { temp[0] = key[i - 1, 0]; temp[1] = key[i - 1, 1]; temp[2] = key[i - 1, 2]; temp[3] = key[i - 1, 3]; for (int j = 0; j < nb; j++) { if (i % nk == 0) { temp[j] = SubBytes.GetSubByte(key[i - 1, (j + 1) % 4]) ^ Rcon[i / nk, j]; } else if ((nk > 6) && (i % nk == 4)) { temp[j] = SubBytes.GetSubByte(key[i - 1, j]); } key[i, j] = temp[j] ^ key[i - nk, j]; } } for (int i = 0; i < nr + 1; i++) { for (int j = 0; j < 16; j++) { cipherKey[i, j] = key[j / 4 + i * 4, j % 4]; } } return(cipherKey); }
public static string Encrypt(string Source, string Key, byte KeyLengthChoiced = 16) { if (String.IsNullOrEmpty(Source)) { throw new Exception("没有输入明文!"); } int KeyByteLength = Encoding.Default.GetBytes(Key).Length; switch (KeyLengthChoiced) { case 16: { if (KeyByteLength != 16) { throw new Exception("密钥必须为16个字符或8个汉字!"); } break; } case 24: { if (KeyByteLength != 24) { throw new Exception("密钥必须为24个字符或12个汉字!"); } break; } case 32: { if (KeyByteLength != 32) { throw new Exception("密钥必须为32个字符或16个汉字!"); } break; } default: { throw new Exception("所选密钥位数错误,请选择16、24或32位密匙"); } } int[,] key = KeyExpansion.GetKeyExpansion(Key); int[,] cipher = Encryption.Getencryption(Source, key); StringBuilder strB = new StringBuilder(); for (int i = 0; i < cipher.GetLength(0); i++) { for (int j = 0; j < 16; j++) { StringBuilder s = new StringBuilder(); byte[] buf = new byte[2]; s = SubBytes.GetStr(cipher[i, j]); buf[0] = Convert.ToByte(s.ToString(0, 4), 2); buf[1] = Convert.ToByte(s.ToString(4, 4), 2); strB.Append(alphabet[buf[0]] + "" + alphabet[buf[1]]); } } return(strB.ToString()); }
public static int[,] Getencryption(string str, int[,] key) { str = str.ToLower(); StringBuilder strB = new StringBuilder(str); if (strB.Length % 16 != 0) { int len = strB.Length; for (int i = 0; i < 32 - len % 32; i++) { strB = strB.Append(" "); } } byte[] buf = Encoding.UTF8.GetBytes(strB.ToString()); int[] cipherkey = new int[16]; int[,] plain = new int[buf.Length / 16, 16]; int[,] ciphertext = new int[buf.Length / 16, 16]; int[] plaintext = new int[16]; StringBuilder s = new StringBuilder(100000); for (int i = 0; i < buf.Length; i++) { for (int j = 7; j >= 0; j--) { s = s.Append(buf[i] >> j & 1); } } for (int i = 0; i < plain.GetLength(0); i++) { for (int j = 0; j < 16; j++) { plain[i, j] = Convert.ToInt32(s.ToString(j * 8 + i * 128, 8), 2); } } for (int i = 0; i < plain.GetLength(0); i++) { for (int h = 0; h < 16; h++) { cipherkey[h] = key[0, h]; plaintext[h] = plain[i, h]; } plaintext = AddRoundKey(plaintext, cipherkey); for (int j = 0; j < key.GetLength(0) - 2; j++) { for (int h = 0; h < 16; h++) { cipherkey[h] = key[j + 1, h]; } for (int h = 0; h < plaintext.Length; h++) { plaintext[h] = SubBytes.GetSubByte(plaintext[h]); } plaintext = ShiftRows(plaintext); plaintext = MixColumn.GetMixColumn(plaintext); plaintext = AddRoundKey(plaintext, cipherkey); } for (int h = 0; h < 16; h++) { cipherkey[h] = key[key.GetLength(0) - 1, h]; } for (int h = 0; h < plaintext.Length; h++) { plaintext[h] = SubBytes.GetSubByte(plaintext[h]); } plaintext = ShiftRows(plaintext); plaintext = AddRoundKey(plaintext, cipherkey); for (int j = 0; j < 16; j++) { ciphertext[i, j] = plaintext[j]; } } return(ciphertext); }
public static int[,] Getdecryption(string str, int[,] key) { int[] cipherkey = new int[16]; str = str.ToLower(); char[] ch = str.ToCharArray(); int[,] cipher = new int[str.Length / 32, 16]; int[,] plian = new int[str.Length / 32, 16]; int[] plaintext = new int[16]; StringBuilder s = new StringBuilder(100000); for (int i = 0; i < str.Length; i++) { for (int j = 3; j >= 0; j--) { s = s.Append(Decryption.GetNum(ch[i]) >> j & 1); } } for (int i = 0; i < cipher.GetLength(0); i++) { for (int j = 0; j < 16; j++) { cipher[i, j] = Convert.ToInt32(s.ToString(j * 8 + i * 128, 8), 2); } } for (int i = 0; i < cipher.GetLength(0); i++) { for (int h = 0; h < 16; h++) { cipherkey[h] = key[key.GetLength(0) - 1, h]; plaintext[h] = cipher[i, h]; } plaintext = AddRoundKey(plaintext, cipherkey); for (int j = key.GetLength(0) - 2; j > 0; j--) { for (int h = 0; h < 16; h++) { cipherkey[h] = key[j, h]; } for (int h = 0; h < plaintext.Length; h++) { plaintext[h] = SubBytes.GetByteSub(plaintext[h]); } plaintext = InvShiftRows(plaintext); plaintext = MixColumn.InvMixColumn(plaintext); plaintext = AddRoundKey(plaintext, cipherkey); } for (int h = 0; h < 16; h++) { cipherkey[h] = key[0, h]; } for (int h = 0; h < plaintext.Length; h++) { plaintext[h] = SubBytes.GetByteSub(plaintext[h]); } plaintext = InvShiftRows(plaintext); plaintext = AddRoundKey(plaintext, cipherkey); for (int j = 0; j < 16; j++) { plian[i, j] = plaintext[j]; } } return(plian); }