Die Community zu .NET und Classic VB.
Menü

Crypto API

 von 

Übersicht 

Wer heutzutage Daten über das Internet versenden will, sei es in Form von Passwörtern, Seriennummern oder einfach nur Daten für ein Fernwartungsprogramm, dem wird schnell klar, dass die Unsicherheit im Netz allgemein sehr stark gestiegen ist. Dies liegt wohl auch daran, dass jetzt die Hacker Tools schreiben, mit denen jeder, der eine Maus bedienen kann, einen Windows oder UNIX-Rechner/Server hacken kann. Zurück zum Thema: Ich möchte hier für euch die Verschlüsselung eurer Daten ein bisschen näher bringen und beschreibe zum diesem Thema die Verschlüsselung per Crypto-API, welche sich in jedem Windows-System in der Advapi32.dll befindet.

Mit freundlichen Grüßen

Tim

Vorwort  

Ich möchte darauf hinweisen, dass dieses Tutorial weder selbst gebaute Verschlüsselungs- methoden enthält, noch die Funktionsweise der Crypto-API dokumentiert. Hier wird lediglich beschrieben, wie man diese Funktionen in sein VB-Programm einbindet.

Ablauf der Verschlüsselung  

Als erstes müssen wir anmelden, dass wir etwas verschlüsseln wollen (ein CSP-Handle wird erstellt). Nun folgt der Verschlüsselungsvorgang bzw der Entschlüsselungsvorgang, der der API nun den Text und das Passwort für die Ver/Entschlüsselung mitteilt und als Rückgabewert den bearbeiteten Text erhält. Als letztes folgt nun die Abmeldung des CSP-Handles und wir haben unseren Text mit 128-Bit ver/entschlüsselt.

Die (wichtige) Funktion StartSession  

Um überhaupt zu verschlüsseln müssen wir uns einen CSP-Handler erstellen. Ohne ihn geht nichts. Wir schreiben uns dafür eine Funktion, da wir ja sicher noch mehr als einen Text verschlüsseln wollen. Wenn wir nun jedesmal ein Handle erstellen und schließen, würde das ersten lange dauern und zweitens eine ganze Menge an Resourcen verschlingen. Wir erstellen also einen Handle mit folgender Funktion:

CryptAcquireContext(hCryptProv, KEY_CONTAINER, _
SERVICE_PROVIDER, PROV_RSA_FULL, CRYPT_NEWKEYSET)

Listing 1

Dieser Aufruf gibt einen Long-Wert zurück, der sagt ob unsere Anfrage erfolgreich war oder nicht. Ist dieser Wert gleich Null, versuchen wir mit

CryptAcquireContext(hCryptProv, KEY_CONTAINER, _
SERVICE_PROVIDER, PROV_RSA_FULL, 0)

Listing 2

einen bereits erstellten Handle zu benutzen. Schlägt auch das fehl, hilft nur noch eine Fehlermeldung.

Das Erstellen der SessionKeys  

Da wir ja eine sichere Verschlüsselung wollen, machen wir uns für jede Verschlüsselung einen Key, den wir aus einem Passwort erstellen, welches sich der Benutzer aussuchen kann. Die Funktion die wir nun schreiben, erhält dann den String, welcher das Passwort enthält und gibt uns dann den SessionKey zurück, mit dem der Rest der Verschlüsselung läuft. Dazu wird als erstes ein Hash erstellt.

CryptCreateHash(hCryptProv, CALG_SHA, 0, 0, hHash)

Listing 3

Die hier benuzte Konstande CALG_SHA gibt uns einen 160-Bit Hash zurück, der mehr Sicherheit bietet als ein 128-Bit Hash, als wenn er durch ein CALG_MD5 an dieser Stelle erstellt worden wäre. Wenn dies einen Fehler zurück gibt, dann geben auch wir eine Fehlermeldung aus. Dann wird mit Hilfe des Hashes aus dem Passwort ein Key erstellt.

Verschlüsselung  

Die Verschlüsselung besteht nun eigentlich nur noch darin, eine Funktion zu schreiben, die die Funktion EncryptDecrypt aufruft, welche jetzt gleich beschrieben wird.

Encrypt / Decrypt  

Diese Funktion erledigt das eigentlich Verschlüsseln oder Entschlüsseln. Sie verbindet alle Funktionen, die wir vorher geschrieben haben. Sie holt sich einen Key aus dem gelieferten Passwort. Außerdem wird beim Verschlüsseln ein String erstellt, der zufällig gewählte Daten enthält, die zusätzlich noch die Verschlüsselung sicherer machen, da sie eben zufällig sind. Anschließend rufen wir noch die Funktionen für das Ent- bzw Verschlüsseln auf, geben den bearbeiteten Text zurück und vernichten den Key für die Session (er wird jedesmal neu erstellt).

Entschlüsselung  

Die Entschlüsselung macht im Prinzip das gleiche wie die Verschlüsselung, nämlich sie ruft EncryptDecrypt auf, lässt jedoch einen Parameter weg und veranlasst so die Entschlüsselung.

EndSession  

Diese Funktion vernichtet eigentlich nur den Key und meldet unseren Handle ab, um so die Resourcen wieder frei zu geben.

Ergänzung - SALT  

Salt-Problem

Wie ein paar praktische Versuche gezeigt haben, gibt es bei dem beigelegten Beispielprojekt insofern ein Problem, weil SaltValues verwendet werden.

Ein SaltValue ist ein zufällig erzeugter Wert, welcher mit der API-Funktion CryptGenRandom erzeugt wird. CryptGenRandom erzeugte i.d.R. zufälligere Werte als die VB-Rnd-Funktion. Der verwendete Algorithmus hängt vom verwendeten CSP ab.

Dieser zufällige Wert wird an das Passwort angehängt um die Übertragung noch sicherer zu machen. SaltValues werden i.d.R. mehrmals während der Übertragung, sofern es sich um dauerhafte Verbindungen(z.B. SSL) handelt, geändert. Am Anfang einer Sitzung können sie auch ohne Probleme unverschlüsselt übertragen werden. Aufgrund der Tatsache, dass sie nur ein Teil des Passwortes sind, besteht hier keine Gefahr.

Das Problem im Beispielprojekt besteht jetzt darin, dass wenn man den verschlüsselten Text z.B. in die Zwischenablage kopiert und man anschließend des Programm neustartet, schlägt die Entschlüsselung, des wieder eingefügten Textes, fehlt.

Dies liegt daran, dass die verwendete Klasse den SaltValue zwischenspeichert. Während einer Programmsitzung ist es also kein Problem, die Funktionen der Klasse zu nutzen.

Will man jedoch Daten beim nächsten Programmaufruf wieder decodieren, so muss man zusätzlich noch den SaltValue zwischenspeichern und beim Programmstart wieder setzen, da ohne ihn eine erfolgreiche Entschlüsselung ja nicht möglich ist.

Hierzu sollte man der Klasse die Eigenschaft SaltValue hinzufügen, mit der man dann strSALT lesen und schreiben kann.

Der SaltValue kann beim verschlüsselten Text gespeichert werden.

Schlusswort  

Ich hoffe, euch hat dieses Tutorial beim Lesen genauso viel Spaß gemacht, wie mir beim Schreiben. Wie schon gesagt, wenn noch Fehler oder Unverständlichkeiten auftreten, schreibt mir bitte eine E-Mail, oder sagt es mir im ICQ (Nr: 132557920). Ansonsten bleibt mir nur noch euch viel Spaß und mehr Sicherheit mit diesem Source zu wünschen!

Tutorial und Beispielprojekt als Download [6300 Bytes]

Ihre Meinung  

Falls Sie Fragen zu diesem Tutorial haben oder Ihre Erfahrung mit anderen Nutzern austauschen möchten, dann teilen Sie uns diese bitte in einem der unten vorhandenen Themen oder über einen neuen Beitrag mit. Hierzu können sie einfach einen Beitrag in einem zum Thema passenden Forum anlegen, welcher automatisch mit dieser Seite verknüpft wird.