/// <summary> /// Create a new TP file for use in stenography from a file. /// </summary> /// <param name="file">The location of the file.</param> /// <param name="key">The key to use in encrypting the data file.</param> public TP_File(string file, string key) { byte[] fileBytes = TP_Encrypt.Encrypt(File.ReadAllBytes(file), key); string fileName = ShortFileName(file); // Create the fixed size header byte[] header = new byte[128]; int fileNameMaxLength = header.Length - 4 - 1 - 3; // First 4 bytes are for the file length header[0] = (byte)(fileBytes.Length >> 24); header[1] = (byte)((fileBytes.Length >> 16) & 0xFF); header[2] = (byte)((fileBytes.Length >> 8) & 0xFF); header[3] = (byte)(fileBytes.Length & 0xFF); // Next byte is for the file name length header[4] = (byte)Math.Min(fileNameMaxLength, fileName.Length); // Last 3 bytes for the signature code header[header.Length - 3] = (byte)(SIGNATURE[0]); header[header.Length - 2] = (byte)(SIGNATURE[1]); header[header.Length - 1] = (byte)(SIGNATURE[2]); // Save the file name for (int i = 0; i < Math.Min(fileNameMaxLength, fileName.Length); i++) { header[5 + i] = (byte)(fileName.ToCharArray()[i]); } // Encrypt the header header = TP_Encrypt.Encrypt(header, key); // Make enough space for both the header and the file byte[] allBytes = new byte[header.Length + fileBytes.Length + 1]; // Save the header to the data to be written to the image for (int i = 0; i < header.Length; i++) { allBytes[i] = header[i]; } // Save the file data for (int i = 0; i < fileBytes.Length; i++) { allBytes[i + header.Length] = fileBytes[i]; } bytes = allBytes; PadFileBytes(); }
/// <summary> /// Create a new Header decoder /// </summary> /// <param name="input">The byte array extracted from the image</param> /// <param name="key">The key used to initially encrypt the data</param> public TP_Header(byte[] input, string key) { Key = key; // The header is 144 bytes encrypted, but only 128 bytes decrypted if (input.Length > 144) { // Get just the bytes for the header from the data byte[] headerPre = new byte[144]; for (int i = 0; i < headerPre.Length; i++) { headerPre[i] = input[i]; } // Decrypt the header byte[] header = TP_Encrypt.Decrypt(headerPre, key); // See if the decrypted header is actually a header // If IsValid is true, then the image most likely contains a hidden file // There is only a 1 in 2^24 chance (about 0.00000006%) that this will falsely be true IsValid = header[header.Length - 3] == TP_File.SIGNATURE[0] && header[header.Length - 2] == TP_File.SIGNATURE[1] && header[header.Length - 1] == TP_File.SIGNATURE[2]; if (IsValid) { // Get the length of the hidden file FileLength = 0; FileLength |= header[0] << 24; FileLength |= header[1] << 16; FileLength |= header[2] << 8; FileLength |= header[3]; // Get the length of the file name int length = (int)header[4]; FileName = ""; // Get the original file name for (int i = 0; i < length; i++) { FileName += (char)header[i + 5]; } } } else { IsValid = false; } }
/// <summary> /// Save the file represented by this data object. /// </summary> /// <param name="location">The location to save the file.</param> public void Save(string location) { byte[] data = GetFileBytes(); File.WriteAllBytes(location, TP_Encrypt.Decrypt(data, fileHeader.Key)); }