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]);
}
}
}
}