15

今日、私が取り組んでいるアプリケーションの春のセキュリティ バージョンを 3.1.3 から 3.1.4 にアップグレードしたところ、org.springframework.security.authentication.encoding.ShaPasswordEncoderクラスの非推奨警告に気付きました。

org.springframework.security.crypto.password.StandardPasswordEncoderそこで、新しい実装に切り替えました。

私はそれを機能させ、新しいユーザーを登録してアプリケーションにログインできましたが、恐れていたように、以前の ShaPasswordEncoder とカスタム ソルトで生成されたパスワードを使用してログインすることはできません。

多くのユーザーがすでに登録されているデータベースがあるため、古いエンコードされたパスワードを無効にせずに実装を切り替えるにはどうすればよいですか? それは可能ですか?

参照: Spring Security の新しい PasswordEncoder の使用方法

4

3 に答える 3

19

より安全なパスワード エンコーディング メカニズムに切り替えたい場合は、BCryptを使用することをお勧めします。ユーザーを移行するには、次のようなものを使用します。

// 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);
    }
}

パスワード フィールドの形式によって、移行されたユーザーの割合を確認できます。$BCrypt 文字列には、記号で始まる独特の構文があります。

他の回答の 1 つは、このコードが誤って複数のパスワードを同時に更新する可能性があることを指摘しています。質問には、カスタム ソルトが使用されていると記載されていたため、ソルトがランダムに選択された場合、衝突の可能性はごくわずかですが、常にそうであるとは限りません。2 つのパスワードが更新された場合、何が問題になりますか? これにより、アカウントが bcrypt ハッシュから同じパスワードを持っていることを検出できます。いずれにしても、更新を行うには SHA ハッシュが同じである必要があるためです。それが問題であると思われる場合 (たとえば、ソルトの選択が不適切であったり、ソルトなしのハッシュを使用しているなどの理由で)、SQL を変更してこれを検出し、個別の BCrypt ハッシュ値で複数の更新を実行するのは簡単です。

于 2013-06-27T16:50:08.430 に答える
5

受け入れられた回答にコメントを追加しようとしましたが、残念ながら、まだ十分な信用がありません。:(

受け入れられた回答のコード スニペットは、データベース内のパスワードを更新する場所で潜在的に危険であると思います。暗号化時に ShaPasswordEncoder が同じ結果を生成する場合 (これが、古いパスワードが見つかると想定されている理由であり、少なくとも ShaPasswordEncoder の null ソルトを使用してこれが確実に正しいことを確認しました)。パスワードはすべてのユーザー間で一意です。たまたま、システム上の別のユーザーと同じパスワードを共有する可能性があり、その SQL コードはたまたまあなたのパスワードを持っているすべてのユーザーを変更することになります。

最も安全な戦略は、ユーザーのパスワードを更新せず、代わりに ShaPasswordEncoder の最終的な削除を計画する移行戦略を提供することだと思います。

  • 提供されているサンプル コードを使用します。
  • データベースを更新するコードを削除します。
  • 「パスワードを忘れた」または「新しいパスワードを生成する」などの機能を追加して、ShaPasswordEncoder が削除されたときにユーザーが新しいパスワードを作成していないという最終的なケースを処理します。削除された Spring Security にアップグレードするとき、または自分で削除することを選択したときのように。
  • ドキュメントを更新するか、ソフトウェアの次のメジャー リリース バージョンでは、ユーザーがパスワードを再保存するか、前述のパスワード リセット機能を使用する必要があることを明確にします。
  • 移行するためのメジャー バージョン リリース サイクルの猶予期間をユーザーに与えます (ユーザーはおそらくそれを行わず、パスワードのリセットに引っかかるだけです)。
于 2015-08-06T13:51:48.180 に答える