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.
Die Klasse SaltHash
 
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
 
Hinweis
Das Download-Projekt ist ausführlich dokumentiert.
Weitere Links zum Thema
Hashcodes mit MD5 generieren
Verschlüsseln mit DES und TripleDES

Windows-Version
98/SE
ME
NT
2000
XP
Vista
Win 7


Download  (19,5 kB) Downloads bisher: [ 325 ]

Vorheriger Tipp Zum Seitenanfang Nächster Tipp

Startseite | Tipps | Projekte | Tutorials | Bücherecke | VB-/VBA-Tipps | API-Referenz | Komponenten | VB.Net-Forum | VB/VBA-Forum | DirectX-Forum | Foren-Archiv | DirectX | Chat | Spielplatz | Links | Suchen | Stichwortverzeichnis | Feedback | Impressum

Seite empfehlen Bug-Report
Letzte Aktualisierung: Montag, 16. Januar 2012