2010-11-16 8 views
6

Ich bin ein Passwort Salz/Hash-Verfahren für meine .NET-Anwendung zu schreiben, vor allem im Anschluss an die Führung dieses Artikels: http://www.aspheute.com/english/20040105.aspHash auf Unicode Passwort

Grundsätzlich ist der Code, der die gesalzene Hash für die Berechnung ist dies:

Allerdings möchte ich zulassen, dass Benutzer Unicode-Zeichen in ihrem Kennwort verwenden können, wenn sie möchten. (Dies scheint eine gute Idee; kann jemand einen Grund denken, ist es nicht?)

Allerdings weiß ich nicht eine Tonne über wie Unicode funktioniert, und ich mache mir Sorgen, wenn ich nur beide Referenzen von System.Text.Encoding.ASCII zu ändern System.Text.Encoding.Unicode kann der Hash-Algorithmus einige Byte-Kombinationen erzeugen, die keine gültigen Unicode-Zeichen bilden und der GetString-Aufruf wird ausflippen.

Ist dies ein gültiges Anliegen, oder wird es in Ordnung sein?

Antwort

12

Sie sollten keine normale Codierung verwenden, um von beliebigen Binärdaten zurück in eine Zeichenfolge zu konvertieren. Es ist kein kodierter Text - es ist nur eine Sequenz von Bytes. Versuchen Sie nicht, es so zu interpretieren, als ob es "normaler" Text wäre. Ob das ursprüngliche Passwort irgendwelche Nicht-ASCII-Zeichen enthält, spielt dabei keine Rolle - Ihr aktueller Code ist defekt. (Ich würde den verlinkte Artikel mit einer großen Portion Verdacht behandelt einfach auf dieser Basis.)

Ich würde vorschlagen:

  • Verwenden Encoding.UTF8 die Bytes aus dem Passwort zu erhalten. Dadurch kann das Passwort Unicode-Zeichen enthalten. Encoding.Unicode wäre auch hier in Ordnung.
  • Verwenden Sie , um aus dem berechneten Hash zurück in Text zu konvertieren. Base64 wurde speziell entwickelt, um undurchsichtige Binärdaten in Text innerhalb des ASCII-Zeichensatzes darzustellen.
+0

Guter Punkt. Das Problem bezieht sich nicht nur auf die Unicode-Implementierung. Die vorhandene ASCII-Implementierung ist ebenfalls fehlerhaft. –

+0

Vielen Dank für diesen aufschlussreichen Kommentar zur ASCII-Codierung. Das erinnert mich an einen Beitrag von Eric Lippert, dessen Moral lautet: "Benutze kein Kryptosystem, das du nicht vollständig verstehst" (http://blogs.msdn.com/b/ericlippert/archive/2009/12/ 14/use-the-right-tool-für-den-job.aspx). P.S. - Ich habe gerade mein C# in Depth 2ed Ebook erhalten, freue mich darauf, etwas Zeit damit zu verbringen! –

2

Es reicht, die erste Referenz auf Unicode oder UTF-8 zu ändern. Es empfiehlt sich jedoch, die Eingabe zu normalisieren, um verschiedene Arten der Eingabe von Akzenten und dergleichen zu berücksichtigen.

0

Ich mag Jon Lösung besser, aber eine andere Option ist einfach das rohe Hexadezimal als Zeichenfolge speichern. Ersetzen Sie Ihre letzte Zeile mit:

return BitConverter.ToString(computedHash) 

Eine Sache, die Sie betrachten wünschen können Passwort Verstärkung ist.
SHA1 ist sehr schnell, manchmal zu schnell. Ein System wird in der Lage sein, einige Millionen Hashes pro Sekunde zu berechnen. Die Geschwindigkeit ermöglicht es einem Angreifer, einen allgemeinen Wörterbuchangriff (einschließlich Varianten in Groß- und Kleinschreibung) und Nummernerweiterungen zu versuchen. Die Geschwindigkeit von SHA1 ermöglicht es, dass ein breiter Wörterbuchraum in einer angemessenen Zeit fertiggestellt werden kann, wodurch die meisten Benutzerkennwörter gebrochen werden.

Eine Methode zur Stärkung der Passwörter besteht darin, sie mehrfach zu hashen, was die CPU-Anforderungen des Hash erhöht. Nimm die Ausgabe des SHA1-Hash und gib sie als Eingabe für eine zweite Runde weiter. Mach das mindestens 1000 mal. Dies verlangsamt die Hash-Berechnung für Sie und einen Angreifer. Für Ihre Benutzer verzögert sich der Zugriff um eine geringfügige Zeit; Die Routine kehrt in 0,01 Sekunden statt in 0,0001 Sekunden zurück. Bei einem Brute-Force-Angriff haben Sie jedoch die Ausführungszeit um den Faktor 1000 erhöht.

Sie können Ihre eigenen aber rollen.net framework exponiert eine Klasse, genau das zu tun: System.Security.Cryptography.Rfc2898DeriveBytes

RFC2898 verwendet SHA1-Algorithmus und akzeptiert Klartext, Salz und Anzahl der Iterationen. Es kann einen Schlüssel mit variabler Länge ausgeben.

http://msdn.microsoft.com/en-us/library/system.security.cryptography.rfc2898derivebytes.aspx

Verwandte Themen