1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
|
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]);
}
}
}
}
|