LukOnline Geschrieben 8. Dezember 2010 Geschrieben 8. Dezember 2010 Hallo zusammen! Ich möchte mit einer C#-Anwendung Bilder Ver- und Entschlüsseln. Nach einiger Recherche bin ich auf den Vernam-Algorithmus aufmerksam gewurden: Schnelles verschlüsseln von Bilder etc - Entwickler-Forum Das funktioniert auch soweit ganz gut, nur habe ich ein Problem bei der Anpassung. Ich möchte als Schlüssel keine Zufallsdaten, sondern einen festen String. Statt der Schlüssel.dat übergebe ich also den String [B]EncryptImage(originalImage, "TestBild_verschlüsselt.jpg", "Passwort");[/B] Folgendes kommentiere ich aus: // Random rnd = new Random(); // rnd.NextBytes(keyBytes); // Schlüssel speichern: // using (FileStream fs = new FileStream(keyFile, FileMode.Create)) // { // fs.Write(keyBytes, 0, keyBytes.Length); // } Doch wie erzeuge ich nun meinen Byte-Schlüssel aus dem Passwort? Es wurde ja geschrieben, dass die Bytes des Schlüssels gleich denen des Passworts sein müssen. Ich muss also das Passwort solange verlängern bis die Byteanzahl stimmt? Wie mache ich das? Kann mir bitte jemand helfen? Danke schonmal, Lukas Zitieren
LukOnline Geschrieben 8. Dezember 2010 Autor Geschrieben 8. Dezember 2010 OK, ich bins schon wieder =) Habe die Lösung doch noch gefunden! // using System.Collections.Generic; // using System.Text; using System; using System.Drawing; // Verweis einbinden! using System.IO; namespace VernamVerschlüsselung { class Program { static void Main() { // Bild von Datei einlesen: Image originalImage = Image.FromFile("TestBild.jpg"); // Bild verschlüsseln: EncryptImage(originalImage, "TestBild_verschlüsselt.jpg", "Passwort"); // Bild entschlüsseln: Image newImage = DecryptImage("TestBild_verschlüsselt.jpg", "Passwort"); // Bild in Datei speichern: newImage.Save("TestBild_entschlüsselt.jpg"); } private static void EncryptImage(Image img, string encryptedFile, string keyFile) { // Verschlüsselung des Bildes int Laenge = keyFile.Length; int Zeichen = 0; ImageConverter ic = new ImageConverter(); byte[] originalBytes = (byte[])ic.ConvertTo(img, typeof(byte[])); // Schlüssel erzeugen - Länge genau wie die originalen Bytes byte[] keyBytes = new byte[originalBytes.Length]; // schreibe den Bytecode des Passwortes immer wieder, bis das Array keyBytes voll ist for (int i = 0; i < keyBytes.Length; i++) { keyBytes[i] = StringToByteArray(keyFile)[Zeichen]; Zeichen++; if (Zeichen == Laenge) { Zeichen = 0; } } // Bild mit Vernam-Algorithmus verschlüsseln (XOR) byte[] encryptedBytes = new byte[originalBytes.Length]; Vernam(originalBytes, keyBytes, ref encryptedBytes); // Speichern des verschlüsselten Bildes using (FileStream fs = new FileStream("TestBild_verschlüsselt.jpg", FileMode.Create)) { fs.Write(encryptedBytes, 0, encryptedBytes.Length); } } private static Image DecryptImage(string encryptedFile, string keyFile) { // Entschlüsselung des Bildes int Laenge = keyFile.Length; int Zeichen = 0; // Einlesen der verschlüsselten Bytes: byte[] encryptedBytes; using (FileStream fs = new FileStream(encryptedFile, FileMode.Open)) { encryptedBytes = new byte[fs.Length]; fs.Read(encryptedBytes, 0, (int)fs.Length); } // Array für Schlüssel-Bytes erzeugen - Länge genau wie die verschlüsselten Bytes byte[] keyBytes = new byte[encryptedBytes.Length]; // schreibe den Bytecode des Passwortes immer wieder, bis das Array keyBytes voll ist for (int i = 0; i < keyBytes.Length; i++) { keyBytes[i] = StringToByteArray(keyFile)[Zeichen]; Zeichen++; if (Zeichen == Laenge) { Zeichen = 0; } } // Entschlüsseln: byte[] originalBytes = new byte[encryptedBytes.Length]; Vernam(encryptedBytes, keyBytes, ref originalBytes); // Image aus dem Byte-Array erzeugen: ImageConverter ic = new ImageConverter(); return ic.ConvertFrom(originalBytes) as Image; } private static void Vernam(byte[] inBytes, byte[] keyBytes, ref byte[] outBytes) { // Prüfen der Argumente: if ((inBytes.Length != keyBytes.Length) || (keyBytes.Length != outBytes.Length)) throw new ArgumentException("Ungleiche Länge"); // XOR: for (int i = 0; i < inBytes.Length; i++) { outBytes[i] = (byte)(inBytes[i] ^ keyBytes[i]); } } private static byte[] StringToByteArray(string str) { // diese Methode Konvertiert einen String in Bytes System.Text.ASCIIEncoding enc = new System.Text.ASCIIEncoding(); return enc.GetBytes(str); } } } Zitieren
LukOnline Geschrieben 20. Dezember 2010 Autor Geschrieben 20. Dezember 2010 Hallo zusammen, mir ist da noch etwas interessantes eingefallen. Wenn die Vernam-Verschlüsselung einfach auf XOR basiert, dann kann ich natürlich ohne das Passwort nicht entschlüsseln. Aber ein Problem bildet sich ab: Wenn ich die verschlüsselte und die Original-Datei habe, kann ich das Passwort errechnen, oder sehe ich das falsch? :-O Wie kann man dem entgegenwirken? Das Passwort im Quellcode modifizieren? Vielleicht die einzelnen Chars verwürfeln? Ist für die Verwürfelung ein weiterer Schlüssel angebracht? Oder vielleicht eine monoalphabetische Chiffrierung? Würde mich über eure Antworten freuen! Gruß Luk Zitieren
Klotzkopp Geschrieben 22. Dezember 2010 Geschrieben 22. Dezember 2010 Aber ein Problem bildet sich ab: Wenn ich die verschlüsselte und die Original-Datei habe, kann ich das Passwort errechnen, oder sehe ich das falsch? :-ONein, aber inwiefern ist das ein Problem? Wenn du die Originaldatei hast, brauchst du das Passwort doch sowieso nicht mehr. Zitieren
LukOnline Geschrieben 22. Dezember 2010 Autor Geschrieben 22. Dezember 2010 (bearbeitet) Ja, da hast du recht, aber es geht ja nicht nur um das eine Bild. Mit dem gleichen Passwort sind noch andere Bilder und eine Access DB geschützt (Ich weiß, dass der Access-Schutz nur eine minimale Hürde ist). Das Problem ist halt einfach, dass ich das Passwort dann ja im Klartext hätte, wenn ich die beiden Bilder mit xor verknüpfe. Und das ist doch schlecht... Deswegen könnte man das Passwort ja vorher im Quellcode chiffrieren. Z.b. 1. Groß / Kleinschreibung vertauschen. 2. Die Buchstaben wie folgt vertauschen. Nennt sich monoalphabetische Chiffre. ABCDEFGHIJKLMNOPQRSTUVWXYZ HIJKLMNOPQRSTUVWXYZABCDEFG (das ganze nochmal mit Kleinschreibung) 3. Das Wort in sich verwürfeln: Tausche Buchstabe [3] mit [0],... Oder einfach das Passwort rückwärts schreiben. 4. Zum Schluss vielleicht den Buchstaben immer noch in der ASCII Tabelle um X erhöhen. Aus A wird mit einer 3 dann zum Beispiel ein D. (A Dez = 65 + 3 = 68; 68 Dez = D) 5. Ziffern um x erhöhen. Wenn ich dann die Bilder xore komme ich möglicherweise auf sJ1dN9f Und daraus das Passwort wiederherzustellen würde ich als knifflig bis schwer bezeichnen... Solange der Quellcode geheim bleibt. Apropos: Wie sieht es überhaupt aus mit Decompilern für C#. Funktioniert das oder eher nicht? Danke schonmal, Luk Bearbeitet 22. Dezember 2010 von LukOnline Zitieren
Guybrush Threepwood Geschrieben 22. Dezember 2010 Geschrieben 22. Dezember 2010 Das ist egal ob Decompilieren oder nicht, im Nitfall guckt man mim debugger Zitieren
LukOnline Geschrieben 22. Dezember 2010 Autor Geschrieben 22. Dezember 2010 Und was macht der? Zitieren
Klotzkopp Geschrieben 22. Dezember 2010 Geschrieben 22. Dezember 2010 Ja, da hast du recht, aber es geht ja nicht nur um das eine Bild. Mit dem gleichen Passwort sind noch andere Bilder und eine Access DB geschützt Wenn es Personen gibt, die nicht alle diese Dateien entschlüsseln dürfen, darfst du für diese Dateien nicht denselben Schlüssel verwenden. Deswegen könnte man das Passwort ja vorher im Quellcode chiffrieren.Wenn das Passwort Bestandteil deines Programms ist, egal in welcher Form, hast du ein grundsätzliches Sicherheitsproblem. Das gehört da einfach nicht hinein. Und daraus das Passwort wiederherzustellen würde ich als knifflig bis schwer bezeichnen... Solange der Quellcode geheim bleibt. Security through obscurity ? Wikipedia Zitieren
Empfohlene Beiträge
Dein Kommentar
Du kannst jetzt schreiben und Dich später registrieren. Wenn Du ein Konto hast, melde Dich jetzt an, um unter Deinem Benutzernamen zu schreiben.