C# :: Aufgabe #89 :: Lösung #3
3 Lösungen

#89
Verschlüsseln durch Verstecken
Fortgeschrittener - C#
von eulerscheZhl
- 27.02.2015 um 18:06 Uhr
Ein Teilgebiet der Kryptographie ist die Steganographie. Hier geht es darum Informationen so zu verstecken, dass andere gar nicht auf die Idee kommen, nach versteckten Informationen zu suchen.
Ein Beispiel, um eine Datei in einem Bild zu verstecken:
Erstelle ein Bytearray mit folgendem Inhalt: die ersten 4 Byte geben die Größe der versteckten Datei in Byte an (big Endian). Danach folgt der Dateiname in ASCII Codierung. Nach einem 0-Byte zu Trennung kommt die zu versteckende Datei selbst.
Diese Daten werden nun in einem Bild versteckt, indem die niederwertigsten beiden Bit eines Pixels für rot, grün und blau überschrieben werden, sodass in jedes Pixel 6 Bit passen. Es wird im oberen linken Eck gestartet und dann die Zeile aufgefüllt, anschließend in der nächsten Zeile fortgefahren.
Das Bild im Anhang wurde auf die beschriebene Weise manipuliert.
Schreibe ein Programm, das die versteckten Daten wieder sichtbar macht.
Ein Beispiel, um eine Datei in einem Bild zu verstecken:
Erstelle ein Bytearray mit folgendem Inhalt: die ersten 4 Byte geben die Größe der versteckten Datei in Byte an (big Endian). Danach folgt der Dateiname in ASCII Codierung. Nach einem 0-Byte zu Trennung kommt die zu versteckende Datei selbst.
Diese Daten werden nun in einem Bild versteckt, indem die niederwertigsten beiden Bit eines Pixels für rot, grün und blau überschrieben werden, sodass in jedes Pixel 6 Bit passen. Es wird im oberen linken Eck gestartet und dann die Zeile aufgefüllt, anschließend in der nächsten Zeile fortgefahren.
Das Bild im Anhang wurde auf die beschriebene Weise manipuliert.
Schreibe ein Programm, das die versteckten Daten wieder sichtbar macht.
#3

von hollst (13980 Punkte)
- 27.07.2017 um 13:03 Uhr
Habe das Ganze einmal in eine WPF-GUI gepackt. Allerdings wird hier nicht ein Bild in einem Bild versteckt, sondern der Text der linken
Textbox (die "Geheimnachricht"). Das manipulierte Bild wird immer im File "hidden.bpm" abgelegt (im Ordner des Originalbildes) und stets ohne
Nachfrage überschrieben. Man sollte die Datei also umbenennen, wenn man das Bild weiter gebrauchen möchte. Das bmp-Format darf allerdings nicht in z. B. png-Format geändert werden. Dann sind die versteckten Informationen nicht mehr auffindbar.
C#-Code
C#-Code
Textbox (die "Geheimnachricht"). Das manipulierte Bild wird immer im File "hidden.bpm" abgelegt (im Ordner des Originalbildes) und stets ohne
Nachfrage überschrieben. Man sollte die Datei also umbenennen, wenn man das Bild weiter gebrauchen möchte. Das bmp-Format darf allerdings nicht in z. B. png-Format geändert werden. Dann sind die versteckten Informationen nicht mehr auffindbar.

using System; using System.Linq; using System.Text; using System.Windows; using System.Windows.Media; using System.Windows.Media.Imaging; using System.IO; namespace aufgabe_89_wpf { public partial class MainWindow : Window { public MainWindow() { InitializeComponent(); this.UpdateLabels(); } #region some helper methods private static Microsoft.Win32.OpenFileDialog opendialog(string filter) { Microsoft.Win32.OpenFileDialog dlg = new Microsoft.Win32.OpenFileDialog(); dlg.DefaultExt = ".png"; dlg.Filter = filter + "all|*.*"; return dlg; } private void UpdateLabels() { this.lb_loaded_picture.Content = System.IO.Path.GetFileName(this.loaded_picture_file); this.lb_loaded_and_discovered_picture.Content = System.IO.Path.GetFileName(this.loaded_and_discovered_picture_file); } #endregion #region some global variables private static string NL = Environment.NewLine; private string loaded_picture_file = string.Empty; private string loaded_text_file = string.Empty; private string loaded_and_discovered_picture_file = string.Empty; private bool bo_show_discovery_after_creation = false; #endregion #region event handler private void bt_reset_Click(object sender, RoutedEventArgs e) { this.image_org.Source = null; this.image_hid.Source = null; this.tb_hide_info.Clear(); this.tb_discovered_info.Clear(); this.tb_helper_links.Clear(); this.tb_helper_rechts.Clear(); this.loaded_picture_file = string.Empty; this.loaded_text_file = string.Empty; this.loaded_and_discovered_picture_file = string.Empty; this.UpdateLabels(); } private void bt_load_picture_Click(object sender, RoutedEventArgs e) { Microsoft.Win32.OpenFileDialog dlg = opendialog("special graphics|*.bmp;*.jpg;*.jpeg;*.png|"); if(dlg.ShowDialog() == true) { string filename = dlg.FileName; this.loaded_picture_file = filename; this.UpdateLabels(); BitmapImage bi = new BitmapImage(new Uri(filename)); this.image_org.Source = bi; } } private void bt_hide_text_Click(object sender, RoutedEventArgs e) { if (this.loaded_picture_file == string.Empty) return; try { BitmapImage bi = new BitmapImage(new Uri(this.loaded_picture_file)); BitmapSource bitmapSource = new FormatConvertedBitmap(bi, PixelFormats.Default, null, 0); WriteableBitmap wbi = new WriteableBitmap(bitmapSource); int h = wbi.PixelHeight; int w = wbi.PixelWidth; int widthInByte = 4 * w; int[] pixelData = new int[w * h]; wbi.CopyPixels(pixelData, widthInByte, 0); byte[] target = new byte[4 * w * h]; for (var i = 0; i < pixelData.Length; i++) { Byte[] fourbytes = BitConverter.GetBytes(pixelData[i]); fourbytes.CopyTo(target, 4 * i); } char[] chars = this.tb_hide_info.Text.ToCharArray(); Encoding enc = Encoding.UTF8;// BigEndianUnicode; byte[] source = enc.GetBytes(chars); byte[] new_target = target.Hide(source); wbi.WritePixels(new Int32Rect(0, 0, w, h), new_target, widthInByte, 0); this.image_hid.Source = wbi; this.tb_helper_links.Text = new_target.ToMyString(); byte[] hidden_txt = new_target.Discover(); char[] hidden_chars = enc.GetChars(hidden_txt); string s = new string(hidden_chars); string hidden_file = System.IO.Path.GetDirectoryName(this.loaded_picture_file) + "\\hidden.bmp"; this.loaded_and_discovered_picture_file = hidden_file; UpdateLabels(); BitmapSource myBitmapImage = this.image_hid.Source as BitmapSource; if (File.Exists(hidden_file)) File.Delete(hidden_file); myBitmapImage.Save(hidden_file); if (bo_show_discovery_after_creation) this.tb_discovered_info.Text = s; } catch (Exception ee) { this.tb_discovered_info.Text = "not possible to save the file" + NL + NL + ee.Message; } } private void bt_load_text_Click(object sender, RoutedEventArgs e) { Microsoft.Win32.OpenFileDialog dlg = opendialog("txt|*.txt|"); if (dlg.ShowDialog() == true) this.tb_hide_info.Text = System.IO.File.ReadAllText(dlg.FileName); } private void bt_load_and_discover_picture_Click(object sender, RoutedEventArgs e) { Microsoft.Win32.OpenFileDialog dlg = opendialog("graphics|*.bmp|"); if (dlg.ShowDialog() == true) { string filename = dlg.FileName; this.loaded_and_discovered_picture_file = filename; this.UpdateLabels(); BitmapImage bi = new BitmapImage(new Uri(filename)); this.image_hid.Source = bi; BitmapSource bitmapSource = new FormatConvertedBitmap(bi, PixelFormats.Default, null, 0); WriteableBitmap wbi = new WriteableBitmap(bitmapSource); int h = wbi.PixelHeight; int w = wbi.PixelWidth; int widthInByte = 4 * w; int[] pixelData = new int[w * h]; wbi.CopyPixels(pixelData, widthInByte, 0); byte[] target = new byte[4 * w * h]; for (var i = 0; i < pixelData.Length; i++) { Byte[] fourbytes = BitConverter.GetBytes(pixelData[i]); fourbytes.CopyTo(target, 4 * i); } this.tb_helper_rechts.Text = target.ToMyString(); try { byte[] hidden_txt = target.Discover(); Encoding enc = Encoding.UTF8; char[] hidden_chars = enc.GetChars(hidden_txt); string s = new string(hidden_chars); this.tb_discovered_info.Text = s; this.UpdateLabels(); } catch (Exception ee) { this.tb_discovered_info.Text = "no hidden infos discovered" + NL + NL + ee.Message; } } } #endregion } public static class Hide_and_Discover { public static Byte[] Hide(this Byte[] hidden_place, Byte[] source) { if (hidden_place.Length < 4 * (4 + source.Length)) { //die ersten 16 Byte enthalten die arraylaenge von source MessageBox.Show("Inputerror Hide: " + hidden_place.Length.ToString() + " " + source.Length.ToString()); return hidden_place; } Byte[] first4_source = BitConverter.GetBytes(source.Length); Byte[][] targets = hidden_place.Splitt(4 * first4_source.Length); targets[0] = BytesIntoBytes(targets[0], first4_source); targets[1] = BytesIntoBytes(targets[1], source); return targets.Join(); } public static Byte[] Discover(this Byte[] source) { Byte[] first16 = source.GetSubArray(anzahl: 16); Byte[][] bint = new Byte[4][]; for (var i = 0; i < 4; i++) { bint[i] = new Byte[4]; for (var j = 0; j < 4; j++) bint[i][j] = first16[4 * i + j]; } Byte[] forint = new Byte[4]; for (var i = 0; i < 4; i++) forint[i] = bint[i].From4(); forint.Reverse(); int size = BitConverter.ToInt32(forint, 0); Byte[] result = new Byte[size]; int zeiger = 16; for (var i = 0; i < size; i++) { Byte[] next4 = source.GetSubArray(ab: zeiger, anzahl: 4); result[i] = next4.From4(); zeiger += 4; } return result; } private static Byte[] BytesIntoBytes(this Byte[] hidden_place, Byte[] source) { Byte[] result = new Byte[hidden_place.Length]; hidden_place.CopyTo(result, 0); Byte eliminate_last_two = 0xFC; Byte[] filter = new Byte[] { 0x03, 0x0C, 0x30, 0xC0 }; int counter = 0; for (var i = 0; i < source.Length; i++) { Byte b = source[i]; for (Byte j = 0; j < filter.Length; j++) { Byte bs = (Byte)(((Byte)(b & filter[j])) >> (2 * j)); result[counter] = (Byte)((Byte)(result[counter] & eliminate_last_two) ^ bs); counter++; } } return result; } private static Byte[][] Splitt(this Byte[] b, int ab) { Byte[][] result = new Byte[2][]; result[0] = new Byte[ab]; for (var i = 0; i < result[0].Length; i++) result[0][i] = b[i]; result[1] = new Byte[b.Length - ab]; for (var i = 0; i < result[1].Length; i++) result[1][i] = b[i + ab]; return result; } private static Byte[] Join(this Byte[][] b) { Byte[] result = new Byte[b[0].Length + b[1].Length]; b[0].CopyTo(result, 0); b[1].CopyTo(result, b[0].Length); return result; } private static Byte From4(this Byte[] b) { Byte maske = 0x03, result = 0x00; for (var i = 0; i < b.Length; i++) { Byte value = (Byte)((b[i] & maske) << 2 * i); result = (Byte)(result ^ value); } return result; } private static Byte[] GetSubArray(this Byte[] b, int ab = 0, int anzahl = 1) { Byte[] result = new Byte[anzahl]; for (var i = 0; i < anzahl; i++) result[i] = b[i + ab]; return result; } } public static class MyExtensions { public static string ToMyString(this byte[] b) { StringBuilder sb = new StringBuilder(); sb.AppendLine(b.Length.ToString("n0")); for (var i = 0; i < b.Length; i++) { if (i % 16 == 0) sb.AppendLine(); sb.Append(String.Format("{0:X2} ", b[i])); } return sb.ToString(); } public static void Save(this BitmapSource image, string filePath) { BitmapEncoder encoder = new BmpBitmapEncoder();// PngBitmapEncoder(); encoder.Frames.Add(BitmapFrame.Create(image)); using (var fileStream = new System.IO.FileStream(filePath, System.IO.FileMode.Create)) { encoder.Save(fileStream); } } } }

<Window x:Class="aufgabe_89_wpf.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:local="clr-namespace:aufgabe_89_wpf" mc:Ignorable="d" Title="hide and discover demo" Height="600" Width="970" FontFamily="Courier New" Background="{DynamicResource {x:Static SystemColors.HighlightBrushKey}}" WindowState="Maximized"> <Grid> <TabControl VerticalContentAlignment="Stretch" HorizontalContentAlignment="Stretch" TabStripPlacement="Bottom"> <TabItem Header=" main "> <Grid x:Name="grid_tab_0" Margin="0,3,0,0" Background="{DynamicResource {x:Static SystemColors.GradientInactiveCaptionBrushKey}}"> <Grid.ColumnDefinitions> <ColumnDefinition Width="1*"/> <ColumnDefinition Width="1*"/> </Grid.ColumnDefinitions> <Grid.RowDefinitions> <RowDefinition Height="45"/> <RowDefinition Height="1*"/> <RowDefinition Height="1*"/> <RowDefinition Height="45"/> </Grid.RowDefinitions> <GridSplitter Grid.Column="1" HorizontalAlignment="Left" Margin="0,10" Grid.Row="1" Grid.RowSpan="3" Width="5"/> <GridSplitter Grid.Row="1" ResizeDirection="Rows" HorizontalAlignment="Stretch" Height="5" VerticalAlignment="Bottom" Grid.ColumnSpan="2"/> <Image x:Name="image_org" Margin="10" Grid.Row="1"/> <Image x:Name="image_hid" Margin="10" Grid.Row="1" Grid.Column="1"/> <StackPanel Margin="5,15,5,5" Orientation="Horizontal"> <Button x:Name="bt_reset" Content=" reset " HorizontalAlignment="Center" VerticalAlignment="Center" Margin="10,0,25,0" Click="bt_reset_Click"/> <Button x:Name="bt_load_picture" Content=" load picture " HorizontalAlignment="Center" VerticalAlignment="Center" Margin="10,0,0,0" Click="bt_load_picture_Click"/> <Button x:Name="bt_load_text" Content=" load text " HorizontalAlignment="Center" VerticalAlignment="Center" Margin="10,0,0,0" Click="bt_load_text_Click"/> <Button x:Name="bt_hide_text" Content=" hide text from textbox " HorizontalAlignment="Center" VerticalAlignment="Center" Margin="50,0,0,0" Click="bt_hide_text_Click"/> </StackPanel> <StackPanel Margin="5,15,5,5" Orientation="Horizontal" Grid.Column="1"> <Button x:Name="bt_load_and_discover_picture" Content=" load picture and discover into textbox " HorizontalAlignment="Center" VerticalAlignment="Center" Margin="10,0,0,0" Click="bt_load_and_discover_picture_Click" /> </StackPanel> <GroupBox Header=" hide information " Margin="5" Grid.Row="2" Background="{DynamicResource {x:Static SystemColors.ActiveCaptionBrushKey}}" BorderThickness="1,0,1,1" Foreground="#FFDE2020" Grid.RowSpan="1" BorderBrush="#FF171819"> <TextBox x:Name="tb_hide_info" Margin="5" VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Auto" AcceptsReturn="True" AcceptsTab="True"/> </GroupBox> <GroupBox Header=" discovered information " Margin="5" Grid.Column="1" Grid.Row="2" Background="{DynamicResource {x:Static SystemColors.ActiveCaptionBrushKey}}" BorderThickness="1,0,1,1" Foreground="#FFDE2020" Grid.RowSpan="1"> <TextBox x:Name="tb_discovered_info" Margin="5" VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Auto" AcceptsReturn="True" AcceptsTab="True"/> </GroupBox> <Label x:Name="lb_loaded_picture" Content="Label" Margin="10,0,0,0" Grid.Row="3" VerticalAlignment="Center"/> <Label x:Name="lb_loaded_and_discovered_picture" Content="Label" Margin="10,0,0,0" Grid.Row="3" Grid.Column="1" VerticalAlignment="Center"/> </Grid> </TabItem> <TabItem Header=" extra text "> <Grid x:Name="grid_tab_1"> <Grid.ColumnDefinitions> <ColumnDefinition Width="1*"/> <ColumnDefinition Width="1*"/> </Grid.ColumnDefinitions> <TextBox x:Name="tb_helper_links" Margin="5" VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Auto" AcceptsReturn="True" AcceptsTab="True" /> <TextBox x:Name="tb_helper_rechts" Margin="5" VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Auto" AcceptsReturn="True" AcceptsTab="True" Grid.Column="1"/> </Grid> </TabItem> </TabControl> </Grid> </Window>
Kommentare:
Für diese Lösung gibt es noch keinen Kommentar
Seite 1 von 0
1