|
Tipp 0182
|
Passwortsicherheit durch SaltHash
|
|
|
Autor/Einsender: Datum: |
|
Michael Werner 14.07.2008 |
|
Entwicklungsumgebung: |
|
VB.Net 2005 |
Framework: |
|
2.0 |
|
|
Bei diesem Tipp geht es um das sichere Speichern von Passwörtern. In .NET 2.0. ist
ein sicherer Salt-Hash mit der Rfc2898DeriveBytes-Klasse möglich, die hier vorgestellt wird.
|
Das Sicherheitsproblem: Schreiben Sie unter keinen Umständen Kennwörter in den Quellcode.
Kennwörter mit vordefiniertem Code können mithilfe von MSIL Disassembler-Tool (Ildasm.exe),
einem Hex-Editor, oder durch das Öffnen der Assembly in einem Text-Editor(z. B. Notepad.exe)
abgerufen werden.
|
Ein Hash (englisch to hash = zerhacken) ist ein Algorithmus, der aus einer großen Quellmenge eine reduzierte Zielmenge abbildet (Streuwertfunktion). Ein Hash sollte
nicht über das Passwort selbst erstellt werden, weil solch direkter Hash leicht zu knacken ist,
da man in Wörterbüchern vergleichen kann, welcher Hashcode welches Wort bedeuten könnte.
|
Hier kommt Rfc2898DeriveBytes ins Spiel, eine Klasse, die mehr Sicherheit durch einen sogenannten
Salt-Hash bietet. Eine neue Instanz der Rfc2898DeriveBytes-Klasse wird mithilfe dreier Parameter,
des Passworts, einer Saltgröße und der Anzahl an Iterationen zum Ableiten des Schlüssels initialisiert.
Dies ermöglicht ein sicheres Hashing. Einfach gesagt, was Salt (Salz) bedeutet: Mit Salt wird
zusätzlich ein Zufallsfaktor in den Hash eingebaut. Salt, ein zufälliger Bytesatz, der an das
Ende des Kennworts angefügt wird, erschwert das nicht autorisierte Entschlüsselung von Meldungen
entscheidend. Ein Wörterbuchangriff wird so praktisch unmöglich gemacht.
|
Zu unserem Tipp: In einer Klasse SaltHash wird aus einer neuen Instanz von Rfc2898DeriveBytes
ein Hash gebildet und in einer Datei binär serialisiert (newPassword). Über eine Funktion
(checkPasswort) wird ein neu übergebenes Passwort geprüft, d.h. ein neuer Hash (newHash) erzeugen
und mit dem in der Datei gespeicherten Hash (origHash), der zunächst deserialisiert wird, verglichen.
Ein textsensitiver Vergleich der HashStrings entscheidet schließlich über die Freigabe. Textsensitiv heißt,
das die Groß- und Kleinschreibung beim Stringvergleich beachtet wird, also bei der Passworteingabe
zu berücksichtigen ist.
|
|
|
|
Imports System.IO
Imports system.IO.Path
Imports System.Security.Cryptography
Imports System.Runtime.Serialization.Formatters.Binary
Imports System.Text
'Sicheres Speichern von Passwörtern
Namespace Michaels
Public Class SaltHash
'Der Pfad für die Serialisation
Private mySaltHashFile As String = _
Combine(Application.UserAppDataPath, "mySaltHash.dat")
'Der für new und check gleiche Salt
Private mySalt As Byte() = New Byte() {0, 1, 2, 3, 4, 5, 6, _
241, 240, 238, 33, 34, 69}
Private iterationCounts As Integer = 2000
Friend Sub newPassword(ByVal pw As String)
Try
Dim ua As New Rfc2898DeriveBytes(pw, mySalt, iterationCounts)
Dim hash As Byte() = ua.GetBytes(32)
Dim stream As New FileStream(mySaltHashFile, FileMode.Create)
Dim converter As New BinaryFormatter()
converter.Serialize(stream, hash)
stream.Close()
Catch ex As ArgumentException
MsgBox(ex.Message)
End Try
End Sub
Friend Function checkPassword(ByVal pw As String) As Boolean
Try
Dim ua As New Rfc2898DeriveBytes(pw, mySalt, iterationCounts)
Dim newHash As Byte() = ua.GetBytes(32)
'Deserialisierung:
Dim stream As New FileStream(mySaltHashFile, FileMode.Open)
Dim converter As New BinaryFormatter()
'Den origHash aus File auslesen
Dim origHash As Byte() = _
CType(converter.Deserialize(stream), Byte())
stream.Close()
'Textsensitiver Vergleich der HashStrings
Dim i As Int32
i = String.Compare(ByteArrayToString(origHash), _
ByteArrayToString(newHash))
If i <> 0 Then
Return False
Else
Return True
End If
Catch ex As ArgumentException
MessageBox.Show(ex.Message)
End Try
End Function
'Hilfsfunktion ByteArrayToString
Private Function ByteArrayToString(ByVal arrInput() As Byte) _
As String
Dim i As Integer
Dim sOutput As New StringBuilder(arrInput.Length)
For i = 0 To arrInput.Length - 1
sOutput.Append(arrInput(i).ToString("X2"))
Next
Return sOutput.ToString()
End Function
End Class
End Namespace |
|
|
|
Das Download-Projekt ist ausführlich dokumentiert.
|
|
|
|
Windows-Version |
98/SE |
|
|
ME |
|
|
NT |
|
|
2000 |
|
|
XP |
|
|
Vista |
|
|
Win
7 |
|
|
|
|
Download (19,5
kB)
|
Downloads bisher: [ 325 ]
|
|
|