Donnerstag, 4. September 2008

Strings verschlüsseln mit C#

Strings mit .NET verschlüsseln ist gar nicht schwer. Durch Zuhilfenahme der TripleDESCryptoServiceProvider-Klasse kann ein String ganz einfach ver- und entschlüsselt werden. Hier ein kleines Beispiel: Das erste was wir brauchen ist ein Initialisierungsvektor und ein Schlüssel.

private readonly byte[] key = new byte[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24 };
private readonly byte[] iv = new byte[] { 65, 110, 68, 26, 69, 178, 200, 219 };
Der Initialisierungsvektor ist der Eingangsparameter mit dem die Startbedingungen für einen kryptografischen Algorithmus gesetzt werden. Der Schlüssel wird für die Verschlüsselung benötigt.Die beiden Werte werden für das Ver- und Entschlüsseln benötigt. Als nächstes der Code zum Verschlüsseln. Die Kommentare erklären eigentlich den Code.
/// <summary>
/// Verschlüsselt einen Eingabestring.
/// </summary>
/// <param name="input">Der zu verschlüsselnde String.</param>
/// <returns>Byte-Array mit dem verschlüsselten String.</returns>
public byte[] StringVerschluesseln(string input)
{
try
{
// MemoryStream Objekt erzeugen
MemoryStream memoryStream = new MemoryStream();

// CryptoStream Objekt erzeugen und den Initialisierungs-Vektor
// sowie den Schlüssel übergeben.
CryptoStream cryptoStream = new CryptoStream(
memoryStream, new TripleDESCryptoServiceProvider().CreateEncryptor(this.key, this.iv), CryptoStreamMode.Write);

// Eingabestring in ein Byte-Array konvertieren
byte[] toEncrypt = new ASCIIEncoding().GetBytes(input);

// Byte-Array in den Stream schreiben und flushen.
cryptoStream.Write(toEncrypt, 0, toEncrypt.Length);
cryptoStream.FlushFinalBlock();

// Ein Byte-Array aus dem Memory-Stream auslesen
byte[] ret = memoryStream.ToArray();

// Stream schließen.
cryptoStream.Close();
memoryStream.Close();

// Rückgabewert.
return ret;
}
catch (CryptographicException e)
{
Console.WriteLine(String.Format(CultureInfo.CurrentCulture, "Fehler beim Verschlüsseln: {0}", e.Message));
return null;
}
}

Bei DES handelt es sich um einen symmetrischen Algorithmus, das heißt zur Ver- und Entschlüsselung wird derselbe Schlüssel verwendet. TripleDES verschlüsselt die Daten dreimal. Um den String wieder herzustellen, dient folgende Funktion:
/// <summary>
/// Entschlüsselt einen String aus einem Byte-Array.
/// </summary>
/// <param name="data">Das verscghlüsselte Byte-Array.</param>
/// <returns>Entschlüsselter String.</returns>
public string StringEntschluesseln(byte[] data)
{
try
{
// Ein MemoryStream Objekt erzeugen und das Byte-Array
// mit den verschlüsselten Daten zuweisen.
MemoryStream memoryStream = new MemoryStream(data);

// Ein CryptoStream Objekt erzeugen und den MemoryStream hinzufügen.
// Den Schlüssel und Initialisierungsvektor zum entschlüsseln verwenden.
CryptoStream cryptoStream = new CryptoStream(
memoryStream,
new TripleDESCryptoServiceProvider().CreateDecryptor(this.key, this.iv), CryptoStreamMode.Read);
// Buffer erstellen um die entschlüsselten Daten zuzuweisen.
byte[] fromEncrypt = new byte[data.Length];

// Read the decrypted data out of the crypto stream
// and place it into the temporary buffer.
// Die entschlüsselten Daten aus dem CryptoStream lesen
// und im temporären Puffer ablegen.
cryptoStream.Read(fromEncrypt, 0, fromEncrypt.Length);

// Den Puffer in einen String konvertieren und zurückgeben.
return new ASCIIEncoding().GetString(fromEncrypt);
}
catch (CryptographicException e)
{
Console.WriteLine(String.Format(CultureInfo.CurrentCulture, "Fehler beim Entschlüsseln: {0}", e.Message));
return null;
}
}

6 Kommentare:

Anonym hat gesagt…

Klasse Anleitung, endlich funktioniert es! Danke!

Unknown hat gesagt…

Stimme dem zu!

Anonym hat gesagt…

wär auch zu schön

Anonym hat gesagt…

ich erhalte beim Entschlüsseln \0\0..\0. Der Algo ist nicht ganz Symetrisch.


Habe folgendes noch hinzugefügt:

cryptoStream.Read(fromEncrypt, 0, fromEncrypt.Length);

byte[] myS= fromEncrypt.Where(c => ((int)c) > 0).ToArray(); // \0 eliminieren

Anonym hat gesagt…

"Der Algo ist nicht ganz Symetrisch." Da hast etwas falsch verstanden: Ein symmetrisches Kryptosystem ist ein Kryptosystem, bei welchem im Gegensatz zu einem asymmetrischen Kryptosystem beide Teilnehmer den gleichen Schlüssel verwenden. Es hat nichts damit zu tun ob die Zeichenkette die du erhälst symetrisch ist oder nicht.

Anonym hat gesagt…

Vielen Dank für das Beispiel!
Ich habe genau nach so einem Ansatz gesucht.

Evtl. wäre es geschickter im hinblick auf Sonderzeichen den String mit System.Text.Encoding.UTF8.GetBytes(input) in ein Byte zu wandeln und umgekehrt mit return System.Text.Encoding.UTF8.GetString(fromEncrypt)); wieder zurück zu wandeln.

Danke noch mal!