Veröffentlicht: 21. Jun 2005
Von Mathias Schiffer
Software muss Kennwörter hinterlegen, um Zugangsberechtigungen abfragen und prüfen können. Hash-Codes sorgen dabei für die nötige Sicherheit.
Kennwörter dauerhaft zu hinterlegen stellt immer ein Risiko dar. Das gilt nicht nur für den gelben Klebezettel am Monitor, in der gut sortierten Schreibtischschublade oder im hintersten Fach der Brieftasche.
Ihre Software zur Prüfung von Berechtigungen hat dabei nämlich ein ganz anderes Problem: Ohne eine Hinterlegung von Daten geht's definitiv nicht, denn die Software muss ja die vom Anwender eingegebenen Zugangsdaten irgendwie auch überprüfen können.
Sie können natürlich die dazu hinterlegten Daten durch beliebig komplexe Verschlüsselung vor unbefugter Einsichtnahme zu sichern versuchen. Ihr tatsächliches Problem verringert sich damit zwar, bleibt im Kern jedoch bestehen: Wird Ihre Verschlüsselung kompromittiert, werden die Daten frei zugänglich.
Geeigneter sind so genannte Hash-Werte. Ein Hash-Wert ist das Ergebnis einer Hash-Funktion, die aus einem Datenaufkommen ("Nachricht") einen normalerweise weniger Speicher verbrauchenden Wert ermittelt, der die Nachricht (nicht deren Inhalt!) im Idealfall eindeutig repräsentieren soll. So können beispielsweise eindeutige Prüfsummen für komplette Dateien gebildet werden, mit deren Hilfe sichergestellt werden kann, dass eine Datenübertragung ohne Fremdeingriffe auf dem Übertragungsweg erfolgreich war.
Für uns noch wichtiger: Hash-Funktionen funktionieren nur in einer Richtung. Das bedeutet, dass man dem Hash-Wert nicht die durch ihn repräsentierte Nachricht entnehmen kann. Sehr wohl aber kann man überprüfen, ob eine Nachricht identisch ist zu der, die zur Erzeugung des Hash-Werts verwendet wurde.
Ein Beispiel aus der Praxis: Microsoft verwendet Hash-Werte bei der so genannten Aktivierung von Produkten ("Windows Product Activation", abgekürzt "WPA"), bei der auf dem Anwendersystem Informationen über die Hardware in einen Hash-Wert umgerechnet werden, der für die "Aktivierung" an Microsoft übergeben werden muss. Wenn wir unterstellen, dass die zu übergebenden Daten echte Hash-Werte sind, dann ist die Information, die zu diesem Hash-Wert geführt hat, für Microsoft auf keinen Fall ermittelbar, sondern lediglich als solche eindeutig. Durchaus kann Microsoft also wie gewünscht erkennen, wenn für dasselbe System bereits eine Aktivierung angefragt wurde.
Ein Hash-Wert bietet also die Möglichkeit, eine Information eindeutig zu identifizieren, nicht aber inhaltlich auswerten zu können: Ein perfektes Konzept für eine notwendige Ablage von Benutzernamen und Kennwörtern für eine Software - die selber weder Benutzernamen noch Kennwörter kennen muss, sondern nur überprüfen muss, ob eine Benutzereingabe gespeicherten Hash-Werten für Benutzernamen und Kennwort entspricht.
Ein weit verbreitetes Verfahren für die Erzeugung von Hash-Werten ist der so genannte MD5-Algorithmus ("Message Digest Algorithm 5"), der aus beliebiger Information einen 128 Bit breiten Hash-Wert berechnet. Diese 16 Bytes reichen bereits aus, um Informationen wie Benutzernamen oder Kennwörter nicht als solche ablegen zu müssen, dennoch aber eindeutig überprüfen zu können.
Die folgende Funktion CreateHash berechnet auf Basis des MD5-Algorithmus mithilfe des .NET Frameworks einen Hash-Wert für einen übergebenen Text (die "Nachricht") und gibt den errechneten Hash-Wert zur Vereinfachung von Speicher- und Vergleichsoperationen als String zurück:
Private Function CreateHash(ByVal SecretInformation As String) As String
' Erzeugt aus dem übergebenen Text einen Hash-Wert auf Basis des MD5-Algorithmus
Dim Hash() As Byte
' MD5-Kryptograhpie-Helfer abholen - der soll für uns die Arbeit machen
Dim MD5CryptoServiceProvider As System.Security.Cryptography.MD5CryptoServiceProvider _
= New System.Security.Cryptography.MD5CryptoServiceProvider
' Hash-Wert aus den Bytes des übergebenen Strings berechnen und im Byte-Array Hash ablegen
Hash = MD5CryptoServiceProvider.ComputeHash(System.Text.Encoding.Default.GetBytes(SecretInformation))
' Inhalte des Byte-Arrays als String zurückgeben
Return System.Text.Encoding.Default.GetString(Hash)
End Function
Mit dieser Hilfsfunktion ist es neben vielen anderen Anwendungsmöglichkeiten ein Leichtes, die hier thematisierten Benutzerberechtigungen ohne Kompromittierbarkeit zu überprüfen.
Das abschließende Code-Beispiel zeigt, wie einfach Sicherheit zu erreichen ist:
' Simulation eines eingelesenen Hash-Werts:
Dim strStoredUsername As String = CreateHash("Mathias Schiffer")
Dim strStoredPassword As String = CreateHash("g7R4p97mt3t")
' Simulation einer zu überprüfenden Benutzereingabe:
Dim strEnteredUsername As String = "Mathias Schiffer"
Dim strEnteredPassword As String = "g7R4p97mt3t"
' Überprüfung der Benutzereingabe
If CreateHash(strEnteredUsername) = strStoredUsername _
AndAlso _
CreateHash(strEnteredPassword) = strStoredPassword Then
' Gespeicherte Hash-Werte sind mit denen der Eingabewerte identisch
MsgBox("Zugang gewährt.", MsgBoxStyle.Information)
Else
' Gespeicherte Hash-Werte unterscheiden sich von den Hashes der Eingabewerte
MsgBox("Zugang verweigert.", MsgBoxStyle.Critical)
End If
Mathias Schiffer widmet sich als freier Softwareentwickler und Technologievermittler größeren Projekten ebenso wie arbeitserleichternden Alltagslösungen. Seit Jahren gibt er sein Wissen in unzähligen Publikationen auch an andere Entwickler und Entscheider weiter. Sie erreichen ihn per E-Mail an die Adresse Schiffer@mvps.org.