最も簡単な解決策は、おそらく「パスワード ハッシュ タイプ」列をデータベースに追加することです。最初は「old」に設定します。ユーザーのログイン時に、新しいアルゴリズムを使用してパスワードを再ハッシュし、データベース タイプを「new」に設定します。
このメソッドの変形は、ハッシュ タイプをハッシュ文字列の一部として保存することです。これは、さまざまなハッシュ形式を明確に区別できる限り同様に機能し、他の必要なパラメーター (ソルトやキーストレッチングの作業係数など) を同じ文字列に含めることができるという利点があります。それぞれの追加フィールドをデータベースに追加する必要があります。
たとえば、これは現代の Unix crypt(3) 実装(およびPHPなどのさまざまな高水準言語の対応する関数) で通常使用されるアプローチです: 古典的な DES ベースの (そして恐ろしく弱い) パスワード ハッシュは次のようabJnggxhB/yWI
になります。 (少し) より現代的なハッシュはのよう$1$z75qouSC$nNVPAk1FTd0yVd62S3sjR1
に見えるかもしれません。1
指定されたハッシュ方法z75qouSC
は、salt とnNVPAk1FTd0yVd62S3sjR1
実際のハッシュであり、デリミタ$
は古いスタイルの DES ハッシュには表示されないため選択されます。
あなたが提案する方法。新しいハッシュは次のように計算されます。
hash = new_hash( old_hash( password ) )
ユーザーがログインするのを待たずに既存のすべてのレコードを更新できるため、場合によっては便利です。ただし、古いハッシュ関数がパスワードのエントロピーを十分に保持している場合にのみ安全です。
たとえば、unsalted MD5のようなかなり古くて弱い暗号化ハッシュ関数でも十分です。その出力は入力全体に依存し、最大 128 ビットのエントロピーを持ちます。これは、ほとんどのパスワードよりも大きい (およびとにかく、総当たり攻撃に耐えるには十分すぎる)。一方、古い DES ベースの crypt(3) 関数を古いハッシュとして使用してこの構造を適用しようとすると、悲惨なことになります。それらの文字の最上位ビットも)。