public static byte[] encrypt(byte[] ina, byte[] key) { Nb = 4; Nk = 4; Nr = Nk + 6; initiv(); int pad_len = 0; byte[] padding = new byte[1]; int i; pad_len = 16 - ina.Length % 16; padding = new byte[pad_len]; padding[0] = (byte)0x80; for (i = 1; i < pad_len; i++) { padding[i] = 0; } byte[] tmp = new byte[ina.Length + pad_len]; byte[] bloc = new byte[16]; w = generateSubkeys(key); int count = 0; for (i = 0; i < ina.Length + pad_len; i++) { if (i > 0 && i % 16 == 0) { bloc = Utilities.xor(bloc, iv); bloc = AESFeistel.encryptBloc(bloc, key); iv = Utilities.extractBits(bloc, 0, 128); Array.Copy(bloc, 0, tmp, i - 16, bloc.Length); } if (i < ina.Length) { bloc[i % 16] = ina[i]; } else { bloc[i % 16] = padding[count % 16]; count++; } } if (bloc.Length == 16) { bloc = Utilities.xor(bloc, iv); bloc = AESFeistel.encryptBloc(bloc, key); iv = Utilities.extractBits(bloc, 0, 128); Array.Copy(bloc, 0, tmp, i - 16, bloc.Length); } return(tmp); }
//encrypted filename: orig_filename.encrypted //returns RSA encrypted key for sharing public static string encrypt(string inp_filepath, string rsa_public_key_xml) { //inp_filepath = System.Web.Hosting.HostingEnvironment.MapPath(inp_filepath); //converting to absolute path string filename = Path.GetFileName(inp_filepath); string enc_filepath = "~/f2_encrypted/encrypted_" + filename; //converting to absolute path enc_filepath = System.Web.Hosting.HostingEnvironment.MapPath(enc_filepath); string af_key = System.Guid.NewGuid().ToString(); byte[] af_key_bytes = Encoding.ASCII.GetBytes(af_key); byte[] inp_file = File.ReadAllBytes(inp_filepath); byte[] enc_file = AESFeistel.encrypt(inp_file, af_key_bytes); HttpContext.Current.Trace.Warn("Output file = " + enc_filepath); File.WriteAllBytes(enc_filepath, enc_file); string enc_af_key = RSA.encrypt(af_key, rsa_public_key_xml); return(enc_af_key); }
private static byte[][] generateSubkeys(byte[] key) { byte[][] tmp = new byte[Nb * (Nr + 1)][]; int i = 0; while (i < Nk) { tmp[i] = new byte[4]; i++; } i = 0; while (i < Nk) { tmp[i][0] = key[i * 4]; tmp[i][1] = key[i * 4 + 1]; tmp[i][2] = key[i * 4 + 2]; tmp[i][3] = key[i * 4 + 3]; i++; } i = Nk; while (i < Nb * (Nr + 1)) { byte[] temp = new byte[4]; for (int k = 0; k < 4; k++) { temp[k] = tmp[i - 1][k]; } if (i % Nk == 0) { temp = AESFeistel.SubWord(AESFeistel.rotateWord(temp)); temp[0] = (byte)(temp[0] ^ (Rcon[i / Nk] & 0xff)); } else if (Nk > 6 && i % Nk == 4) { temp = AESFeistel.SubWord(temp); } tmp[i] = Utilities.xor(tmp[i - Nk], temp); i++; } return(tmp); }
private static byte[][] MixColumns(byte[][] s) { int[] sp = new int[4]; byte b02 = (byte)0x02, b03 = (byte)0x03; for (int c = 0; c < 4; c++) { sp[0] = AESFeistel.FFMul(b02, s[0][c]) ^ AESFeistel.FFMul(b03, s[1][c]) ^ s[2][c] ^ s[3][c]; sp[1] = s[0][c] ^ AESFeistel.FFMul(b02, s[1][c]) ^ AESFeistel.FFMul(b03, s[2][c]) ^ s[3][c]; sp[2] = s[0][c] ^ s[1][c] ^ AESFeistel.FFMul(b02, s[2][c]) ^ AESFeistel.FFMul(b03, s[3][c]); sp[3] = AESFeistel.FFMul(b03, s[0][c]) ^ s[1][c] ^ s[2][c] ^ AESFeistel.FFMul(b02, s[3][c]); for (int i = 0; i < 4; i++) { s[i][c] = (byte)(sp[i]); } } return(s); }
public static byte[] decrypt(byte[] ina, byte[] key) { int i; byte[] tmp = new byte[ina.Length]; byte[] bloc = new byte[16]; initiv(); Nb = 4; Nk = 4; Nr = Nk + 6; w = generateSubkeys(key); for (i = 0; i < ina.Length; i++) { if (i > 0 && i % 16 == 0) { temp = Utilities.extractBits(bloc, 0, 128); bloc = AESFeistel.decryptBloc(bloc, key); bloc = Utilities.xor(bloc, iv); iv = Utilities.extractBits(temp, 0, 128); Array.Copy(bloc, 0, tmp, i - 16, bloc.Length); } if (i < ina.Length) { bloc[i % 16] = ina[i]; } } temp = Utilities.extractBits(bloc, 0, 128); bloc = AESFeistel.decryptBloc(bloc, key); bloc = Utilities.xor(bloc, iv); iv = Utilities.extractBits(temp, 0, 128); Array.Copy(bloc, 0, tmp, i - 16, bloc.Length); tmp = deletePadding(tmp); return(tmp); }
private static byte[][] InvMixColumns(byte[][] s) { int[] sp = new int[4]; byte b02 = (byte)0x0e, b03 = (byte)0x0b, b04 = (byte)0x0d, b05 = (byte)0x09; for (int c = 0; c < 4; c++) { sp[0] = AESFeistel.FFMul(b02, s[0][c]) ^ AESFeistel.FFMul(b03, s[1][c]) ^ AESFeistel.FFMul(b04, s[2][c]) ^ AESFeistel.FFMul(b05, s[3][c]); sp[1] = AESFeistel.FFMul(b05, s[0][c]) ^ AESFeistel.FFMul(b02, s[1][c]) ^ AESFeistel.FFMul(b03, s[2][c]) ^ AESFeistel.FFMul(b04, s[3][c]); sp[2] = AESFeistel.FFMul(b04, s[0][c]) ^ AESFeistel.FFMul(b05, s[1][c]) ^ AESFeistel.FFMul(b02, s[2][c]) ^ AESFeistel.FFMul(b03, s[3][c]); sp[3] = AESFeistel.FFMul(b03, s[0][c]) ^ AESFeistel.FFMul(b04, s[1][c]) ^ AESFeistel.FFMul(b05, s[2][c]) ^ AESFeistel.FFMul(b02, s[3][c]); for (int i = 0; i < 4; i++) { s[i][c] = (byte)(sp[i]); } } return(s); }
//outputs decrypted filepath public static string decrypt(string enc_filepath, string enc_af_key, string rsa_private_key_xml) { //converting to absolute path //enc_filepath = System.Web.Hosting.HostingEnvironment.MapPath(enc_filepath); string filenameNoExt = Path.GetFileName(enc_filepath); //removes .enc string dec_filepath = "~/f4_decrypted/" + filenameNoExt; //converting to absolute path dec_filepath = System.Web.Hosting.HostingEnvironment.MapPath(dec_filepath); string af_key = RSA.decrypt(enc_af_key, rsa_private_key_xml); byte[] af_key_bytes = Encoding.ASCII.GetBytes(af_key); byte[] enc_file = File.ReadAllBytes(enc_filepath); byte[] dec_file = AESFeistel.decrypt(enc_file, af_key_bytes); File.WriteAllBytes(dec_filepath, dec_file); return("~/f4_decrypted/" + filenameNoExt); }
private static byte[] decryptBloc(byte[] ina, byte[] key_array) { byte[] tmp = new byte[ina.Length]; byte[] tmp1 = new byte[ina.Length / 2]; byte[] tmp2 = new byte[ina.Length / 2]; // 2D State Array Declaration byte[][] state = new byte[4][]; int j = 0; while (j < 4) { state[j] = new byte[Nb]; j++; } //Form 2D Array of State for (int i = 0; i < ina.Length; i++) { state[i / 4][i % 4] = ina[i % 4 * 4 + i / 4]; } //Last Round Decrypted state = AESFeistel.AddRoundKey(state, w, Nr); state = AESFeistel.InvShiftRows(state); state = AESFeistel.InvSubBytes(state); //Rounds 6 to 9 Decrypted for (int round = Nr - 1; round >= 6; round--) { state = AESFeistel.AddRoundKey(state, w, round); state = AESFeistel.InvMixColumns(state); state = AESFeistel.InvShiftRows(state); state = AESFeistel.InvSubBytes(state); } //Convert Back to 1D Array for (int i = 0; i < tmp.Length; i++) { tmp[i % 4 * 4 + i / 4] = state[i / 4][i % 4]; } tmp1 = Utilities.extractBits(tmp, 0, 64); tmp2 = Utilities.extractBits(tmp, 64, 64); //FEISTEL CIPHER tmp1 = Feistel.decrypt(tmp1, key_array); tmp2 = Feistel.decrypt(tmp2, key_array); //Join 2 arrays tmp = Utilities.concatBits(tmp2, 64, tmp1, 64); //Covert back to 2D Array for further AES rounds for (int i = 0; i < tmp.Length; i++) { state[i / 4][i % 4] = tmp[i % 4 * 4 + i / 4]; } //Rounds 1 to 5 Decrypted for (int round = 5; round >= 1; round--) { state = AESFeistel.AddRoundKey(state, w, round); state = AESFeistel.InvMixColumns(state); state = AESFeistel.InvShiftRows(state); state = AESFeistel.InvSubBytes(state); } //Initial Round Decryption state = AESFeistel.AddRoundKey(state, w, 0); //Convert back to 1D Array for (int i = 0; i < tmp.Length; i++) { tmp[i % 4 * 4 + i / 4] = state[i / 4][i % 4]; } return(tmp); }