2013-06-21 6 views
13

Heute habe ich die Spring-Sicherheitsversion der Anwendung, an der ich arbeite, von 3.1.3 auf 3.1.4 aktualisiert, und ich bemerkte eine Verwarnungswarnung für die Klasse org.springframework.security.authentication.encoding.ShaPasswordEncoder.Spring security 3.1.4 und ShaPasswordEncoder depreciation

So wechselte ich auf die neue org.springframework.security.crypto.password.StandardPasswordEncoder Implementierung.

Ich hatte es funktioniert und ich bin in der Lage, einen neuen Benutzer und Login in meiner Anwendung zu registrieren, aber, wie ich befürchtet habe, kann ich mich nicht einloggen Passwörter mit dem vorherigen ShaPasswordEncoder und meine benutzerdefinierte Salz generiert.

Da ich eine Datenbank mit vielen Benutzern bereits registriert habe, was soll ich tun, um die Implementierung zu wechseln, ohne die alten codierten Passwörter zu entwerten? Ist es überhaupt möglich?

Siehe auch: How to use new PasswordEncoder from Spring Security

Antwort

17

Wenn Sie zu einem sicheren Passwort-Verschlüsselungsmechanismus wechseln möchten, dann würde ich Ihnen empfehlen, BCrypt zu verwenden. Ich würde so etwas wie diese verwenden, um die Benutzer zu migrieren:

// Implement the old PasswordEncoder interface 
public class MigrateUsersPasswordEncoder implements PasswordEncoder { 
    @Autowired 
    ShaPasswordEncoder legacyEncoder; 
    @Autowired 
    JdbcTemplate template; 

    BCryptPasswordEncoder bcryptEncoder = new BCryptPasswordEncoder(); 

    @Override 
    public String encodePassword(String rawPass, Object salt) { 
     return bcryptEncoder.encode(rawPass); 
    } 

    @Override 
    public boolean isPasswordValid(String encPass, String rawPass, Object salt) { 
     if (legacyEncoder.isPasswordValid(encPass, rawPass, salt)) { 
      template.update("update users set password = ? where password = ?", bcryptEncoder.encode(rawPass), encPass); 
      return true; 
     } 
     return bcryptEncoder.matches(rawPass, encPass); 
    } 
} 

Sie können prüfen, welcher Anteil der Benutzer durch das Format des Passwort-Feld migriert wurden. BCrypt-Strings haben eine unverwechselbare Syntax, die mit einem $ Zeichen beginnt.

Eine der anderen Antworten weist darauf hin, dass dieser Code versehentlich mehrere Kennwörter gleichzeitig aktualisieren kann. Die Frage besagt, dass ein Brauchsalz verwendet wurde, so dass die Wahrscheinlichkeit von Zusammenstößen vernachlässigbar ist, wenn das Salz zufällig ausgewählt wird, aber dies ist möglicherweise nicht immer der Fall. Wenn zwei Passwörter aktualisiert würden, was wäre das Problem? Es wäre dann möglich zu erkennen, dass Accounts dasselbe Passwort von den bcrypt-Hashes haben. Das ist sowieso der Fall, da es erfordert, dass die SHA-Hashes für das Update identisch sind. Wenn Sie denken, dass es ein Problem sein könnte (z. B. wegen schlechter Salzauswahl oder sogar der Verwendung von ungesalzenen Hashes), wäre es trivial, die SQL zu ändern, um dies zu erkennen und mehrere Aktualisierungen mit separaten BCrypt-Hashwerten durchzuführen.

+0

Danke für den Code. Das ist mehr oder weniger das, was Spiff vorgeschlagen hat. Mein Ziel ist es, auf zukünftige Releases von Spring Security aufrüsten zu können, ohne zwei Implementierungen gleichzeitig zu haben, und diese Lösung funktioniert nur, wenn sich jeder Benutzer anmeldet. Ich hoffe, dass eine Implementierung eingeführt wird, die mit der alten kompatibel ist ShaPasswordEncoder. –

+0

Wenn Benutzer sich nie anmelden, kann es sich lohnen, zu entscheiden, ob die Konten (nach einem geeigneten Überprüfungszeitraum) zu warten sind. Wenn sie inaktiv sind, können Sie sie vorübergehend deaktivieren und die Benutzer mailen, die sie auffordern, ihr Passwort zurückzusetzen. Von der Verwendung der alten Passwort-Encoder wird abgeraten, da sie relativ unsicher, fehleranfällig und mit anderen Systemen inkompatibel sind. Die Klassen sind veraltet, um ihre Verwendung in neuen Apps zu verhindern, aber nichts hält Sie davon ab, sie zu verwenden, wenn Sie wirklich keine sicherere Option verwenden möchten. –

1

Das ist eine ausgezeichnete Frage ist und freue mich auf ein paar Antworten zu lesen.

AFAIK es ist unmöglich, in einer einzigen Massenaktualisierung zu tun: Sie können nur die ursprüngliche Zeichenfolge von einem Hash abrufen. Sie müssten während eines Anmeldeversuchs überprüfen, ob das übergebene Passwort mit beiden Strategien übereinstimmt und es bei Bedarf in die neue Strategie konvertieren, aber das bedeutet, dass Sie mit beiden Verschlüsselungsstrategien leben müssen, bis sich alle Benutzer angemeldet haben und somit alle Passwörter vorhanden sind umgewandelt. Nicht sehr praktisch und nicht unbedingt intuitiv für neue Entwickler, die an Bord kommen.

2

Ich habe versucht, einen Kommentar zu der angenommenen Antwort hinzuzufügen, aber leider habe ich noch nicht genug Cred. :(

Ich glaube, das Code-Snippet der akzeptierten Antwort ist potenziell gefährlich, wo es das Passwort in der Datenbank aktualisiert. Wenn der ShaPasswordEncoder die gleichen Ergebnisse bei der Verschlüsselung produziert (weshalb die Annahme gemacht wird, dass das alte Passwort gefunden werden kann) , und ich habe bestätigt, dass dies zumindest mit einem Nullsalz auf dem ShaPasswordEncoder definitiv der Fall ist, können Sie nicht garantieren, dass das Passwort unter allen Benutzern eindeutig ist. Sie könnten zufällig das gleiche Passwort wie ein anderer Benutzer auf dem System teilen Dieser SQL-Code würde am Ende alle Benutzer ändern, die Ihr Passwort haben

Ich denke, die sicherste Strategie ist, das Passwort des Benutzers nicht zu aktualisieren, und stattdessen eine Migrationsstrategie, die für die eventuelle Entfernung des ShaPasswor plant dEncoder.

  • Verwenden Sie den mitgelieferten Beispielcode.
  • Entfernen Sie den Code, der die Datenbank aktualisiert.
  • Fügen Sie eine Funktion wie "Passwort vergessen" oder "Neues Passwort erzeugen" hinzu, um den Fall zu behandeln, dass Benutzer beim Entfernen des ShaPasswordEncoders kein neues Passwort erstellt haben. Entweder bei einem Upgrade auf Spring Security, von dem es entfernt wurde, oder Sie wählen selbst, es zu entfernen.
  • Aktualisieren Sie Ihre Dokumentation oder machen Sie deutlich, dass Benutzer in der nächsten Hauptversion der Software ihre Kennwörter erneut speichern müssen oder die zuvor genannte Funktion zum Zurücksetzen des Kennworts verwenden müssen.
  • Geben Sie dem Benutzer den Kulanzzeitraum eines Hauptversionsfreigabezyklus zum Übergang (sie werden es wahrscheinlich nicht tun und nur in dem Zurücksetzenkennwort gefangen werden).
+0

Das ist ein guter Punkt. Ich denke jedoch nicht, dass es im Vergleich zur bestehenden Situation wirklich gefährlich ist oder dass die Updates verschoben werden sollten. Es ist auch trivial zu umgehen. Ich habe meine Antwort aktualisiert, um zusätzliche Gedanken hinzuzufügen. –