2009-03-14 5 views
6

Unsere webbasierten Anwendungen verfügen über Benutzerkonten, die an Benutzer mit den Kennwörtern gebunden sind, die bei der Kontoerstellung angegeben wurden. Im Fall von Java, wie verarbeitet man das Passwort sicher, bevor es seinen Hash in der Datenbank fortsetzt.Wie speichert man Passwort-Hashes sicher im Speicher, wenn man Konten erstellt?

Um genauer zu sein, wie stellt man sicher, dass die Zeichenfolge, die das Passwort enthält, innerhalb eines ausreichend kurzen Zeitintervalls gesammelt wird?

+0

Dies könnte helfen, Passwort während der Registrierung Prozess zu sichern. Http://wheelersoftware.com/articles/spring-security-hash-salt-passwords.html –

Antwort

6

Wenn Sie die Möglichkeit haben (kann in Webanwendungen schwierig sein), wäre es besser, Kennwörter in Zeichenfeldern zu speichern, als sie in Zeichenfolgen zu speichern. Wenn Sie das Passwort fertig zu speichern können Sie es im Speicher überschreiben, indem Array.fill() Verwendung und die Referenz für den Garbage Collector zur Verfügung stellen durch Verwerfen es:

Arrays.fill(password, ' '); 
password = null; 

Ich habe gerade bemerkt, dass das Passwort nulling ein bisschen paranoid sein würde, aber man kann tun, wenn es Sie beruhigt :)

+0

Wenn dies in einer Webanwendung möglich ist - Lesen Sie das Kennwort aus dem Servlet-Eingabestream in ein Bytearray und füllen Sie das Array nach dem Fortsetzen des Kennworts mit Nullen, dann sollte es sich als praktikabler Ansatz herausstellen. Das OWASP-Java-Projekt verwendet dies in einem Beispiel, aber nicht für persistente Kennwörter. –

+2

Muss dies nicht dazu führen, dass der Garbage Collector den Stack nicht komprimiert und somit eine Kopie des Arrays an anderer Stelle im Speicher belässt? –

+1

@KeeperOfTheSoul: Ja, letztendlich hängt es vom GC-Verhalten ab. Es hängt auch davon ab, ob das Array serialisiert wird oder nicht. Alles in allem wünschte ich mir, dass Java eine SecureString-Klasse ähnlich der von Microsoft .Net hätte. –

4

Wenn Sie den Hash auf der Clientseite erstellen, sollten Sie über dieses Problem nicht nachdenken. Das Plain-Passwort wird niemals an den Server gesendet.

+0

Ja, das ist ein guter Ansatz, aber dann würde das auch nicht gehen Angreifer mit der Fähigkeit, den verwendeten Hash-Algorithmus zu untersuchen? Zugegeben, dass es in gewisser Weise Sicherheit durch Dunkelheit ist, aber es beschränkt die Menge an Informationen, die dem Angreifer zur Verfügung stehen, wie Passwörter gespeichert werden. –

+0

Das wäre eine Option, aber könnte ein Angreifer auch den vom Client generierten Hash nicht abfangen und dann einfach die gleiche HTTP-Anfrage erneut generieren, um sich einzuloggen? –

+0

@Markus, HTTPS wird immer verwendet, daher ist die Wahrscheinlichkeit eines MITM-Angriffs niedrig oder null. –

2

Zwei Wörter: Lokaler Bereich. Die deklarierten Variablen für die Passwortverarbeitung müssen den kleinstmöglichen Umfang haben.

Sobald die Variablen den Gültigkeitsbereich verlassen, sind die Objekte für die Garbage Collection geeignet.

Oft wählen Sie Dinge aus einer Anfrage. Sie möchten eine sehr, sehr kleine Transaktion, die die Anfrage akzeptiert, das Passwort hasht, persistiert und weiterleitet. Die Seite, auf die Sie umleiten, kann dann Inhalte abrufen und alle anderen Verarbeitungen ausführen, die Teil Ihrer Anwendung sind.

1

Es kann nicht garantiert werden, dass Klartextkennwörter aus dem Speicher in Java entfernt werden.

Ein Hacker benötigt jedoch keinen Zugriff auf den Speicher eines Programms, um Klartextpasswörter zu erhalten. Es gibt viel einfachere Möglichkeiten (z. B. das Sniffing der Pakete), so dass es höchst unwahrscheinlich ist, dass sich jemand auf diesen Ansatz verlässt.

Der beste Ansatz ist es, den Client das Passwort verschlüsseln zu lassen, wie @ Mork0075 suggeriert. Während es jedoch bedeutet, dass Sie das Passwort nicht ohne Weiteres erhalten, kann ein Programm immer noch die verschlüsselte Version von Passwörtern erhalten und so tun, als wäre es ein Benutzer. Ein Umweg ist das Verschlüsseln der gesamten Verbindung mit SSL.

All dies ist eher akademisch, da der einfachste Ansatz für einen Hacker ist, die Pakete auf die Datenbank zu überwachen und das Passwort für Ihre Datenbank zu erhalten. Ich vermute, dass der direkte Zugriff auf Ihre Datenbank problematischer ist ... oder vielleicht auch nicht. ;)

+0

Ich versuche, die Passwörter zu schützen, nicht weil ein Angreifer diesen Ansatz versuchen würde - die Box wurde kompromittiert, wenn er einen Blick in den Speicher werfen kann, also gibt es größere Dinge, über die man sich Sorgen machen muss. Ich möchte verhindern, dass Passwörter in einem Java-Heap-Dump erscheinen, der für die Diagnose erstellt wurde. –

0

ein Passwort Herausforderung Verwendung:

  1. Server wählt eine Herausforderung Wert und sendet sie an den Client-
  2. Server führt eine 1-Wege-Übersetzung mit dem Passwort und der Herausforderung, ex. MD5(CONCAT(challenge, password)) und weist es der Sitzung zu.
  3. Klartext-Passwort ist jetzt außerhalb des Bereichs und bereit für die Garbage Collection.
  4. Client führt auch die gleiche Übersetzung durch und sendet das Ergebnis an den Server.
  5. Wenn Server und Client denselben endgültigen Wert auswählen, wird der Client authentifiziert.

Diese Methode verhindert Replay-Attacken, erfordert aber die Wert Herausforderung sehr unberechenbar sein (random) und nicht oft (lang) wiederverwendet.

Das Nur-Text-Passwort ist nur während der Behandlung der ersten Verbindungsanforderung gültig - nicht während der Authentifizierung. Es spielt keine Rolle, wie lange das 1-way-Übersetzungsergebnis im Umfang ist (nicht Müll gesammelt), weil es einen geringen Wiederspielwert hat.

+0

Das wäre gut für den Login-Prozess, aber der Autor fragte nach der Registrierung eines Kontos, so dass Sie auch einen Hash-Wert in einer Datenbank speichern müssen. Dieser Hash kann nicht über einen Abfragewert generiert werden, da er bei der Anmeldung nicht wiederhergestellt werden konnte. –

5

Sie verwenden keine Zeichenfolge. Sie verwenden ein Zeichen [] und überschreiben dann das Zeichen [], wenn Sie fertig sind.

Es gibt absolut keine Garantien, wenn es um Garbage Collection geht (abgesehen davon, dass der Finalizer ausgeführt wird, bevor das Objekt gesammelt wird). Der GC wird möglicherweise nie ausgeführt, wenn er ausgeführt wird, kann die Zeichenfolge, die das Kennwort enthält, niemals in GC angezeigt werden.