Feedback

C# - Verschlüsslung von Dateien mit Vernam

Veröffentlicht von am 9/27/2008
(3 Bewertungen)
In diesem Beispiel zeige ich wie Dateien (im Beispiel eine Bilddatei) mit dem Vernam-Algorithmus verschlüsselt werden können.

Dieses Verfahren ist sehr effizient und sehr sicher (solange der Schlüssel geheim bleibt).

Die Verschlüsselung bei Vernam ist eine einfache XOR-Verschlüsselung.
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", "Schlüssel.dat");

			// Bild entschlüsseln:
			Image newImage = DecryptImage("TestBild_verschlüsselt.jpg", "Schlüssel.dat");

			// Bild in Datei speichern:
			newImage.Save("TestBild_entschlüsselt.jpg");
		}
		//---------------------------------------------------------------------
		/// <summary>
		/// Verschlüsselt ein Bild nach Vernam
		/// </summary>
		/// <param name="img">
		/// zu verschlüsselndes Bild
		/// </param>
		/// <param name="encryptedFile">
		/// Dateiname in dem das verschlüsselte Bild geschrieben wird
		/// </param>
		/// <param name="keyFile">
		/// Dateiname in dem der Schlüssel geschrieben wird
		/// </param>
		private static void EncryptImage(Image img, string encryptedFile, string keyFile)
		{
			// Byte-Array aus dem Bild erstellen (könnte auch über 
			// MemoryStream geschehen)
			/*
			byte[] originalBytes;
			using (MemoryStream ms = new MemoryStream())
			{
				img.Save(ms, ImageFormat.Jpeg);
				originalBytes = ms.ToArray();
			}
			*/
			ImageConverter ic = new ImageConverter();
			byte[] originalBytes = (byte[])ic.ConvertTo(img, typeof(byte[]));

			// Schlüssel erzeugen. Hier wird ein Zufallsschlüssel verwendet:
			byte[] keyBytes = new byte[originalBytes.Length];
			Random rnd = new Random();
			rnd.NextBytes(keyBytes);

			// Schlüssel speichern:
			using (FileStream fs = new FileStream(keyFile, FileMode.Create))
			{
				fs.Write(keyBytes, 0, keyBytes.Length);
			}

			// Bild mit Vernam-Algorithmus verschlüsseln (XOR).
			// Die Schlüssellänge entspricht der Originallänge da der
			// Schlüssel so erzeug worden ist.
			byte[] encryptedBytes = new byte[originalBytes.Length];
			Vernam(originalBytes, keyBytes, ref encryptedBytes);
			
			// Speichern des verschlüsselten Bildes. Da die Information
			// im byte-Array kein gültiges Image darstellt kann es nicht
			// als Image behandelt werden.
			using (FileStream fs =
				new FileStream("TestBild_verschlüsselt.jpg", FileMode.Create))
			{
				fs.Write(encryptedBytes, 0, encryptedBytes.Length);
			}
		}
		//---------------------------------------------------------------------
		/// <summary>
		/// Entschlüsselt ein Bild nach Vernam
		/// </summary>
		/// <param name="encryptedFile">
		/// Dateiname der verschlüsselten Datei
		/// </param>
		/// <param name="keyFile">
		/// Dateiname der Schlüsseldatei (muss den gleichen Inhalt haben wie 
		/// die Datei die beim Verschlüsseln erstellt wurde)
		/// </param>
		/// <returns>
		/// entschlüsseltes Bild
		/// </returns>
		private static Image DecryptImage(string encryptedFile, string keyFile)
		{
			// 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);
			}

			// Einlesen des Schlüssels:
			byte[] keyBytes;
			using (FileStream fs = new FileStream(keyFile, FileMode.Open))
			{
				keyBytes = new byte[fs.Length];
				fs.Read(keyBytes, 0, (int)fs.Length);
			}

			// 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;
		}
		//---------------------------------------------------------------------
		/// <summary>
		/// Führt die Vernam-Verschlüsselung durch
		/// </summary>
		/// <param name="inBytes"></param>
		/// <param name="keyBytes"></param>
		/// <param name="outBytes"></param>
		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]);
			}
		}
	}
}

Kommentare zum Snippet

 

Logge dich ein, um hier zu kommentieren!