web-dev-qa-db-ja.com

安全なパスワード履歴を実装する方法

セキュリティ上の理由から、パスワードはプレーンテキストで保存しないでください。ハッシュを保存する必要があります。また、Rainbowテーブル攻撃を回避するために、ハッシュを慎重に生成する必要があります。

ただし、通常は、最後のnパスワードを保存し、異なるパスワード間の複雑さと変更を最小限に抑える必要があります(ユーザーがPassword_1、Password_2、...、パスワード_n)。これはプレーンテキストのパスワードでは簡単ですが、ハッシュのみを格納することでそれを行うにはどうすればよいでしょうか。

言い換えれば、どのようにして安全なパスワード履歴メカニズムを実装することが可能でしょうか?

23
Wizard79

ログイン時にパスワードを確認するのと同じ方法で、ハッシュを保存し、保存されたハッシュに対して入力したパスワードを確認します。「最小限の」変更を検出するには、数値パターンに基づいて与えられたパスワードから「代替」パスワードを生成する必要があります。

ログイン時に、入力したパスワードをハッシュと照合して検証します。パスワードをプレーンテキストで保存する必要はありません。パスワードを変更する場合も同じトリックが機能します。入力された「最小限の変更」で生成されたパスワードを履歴ハッシュと照合するだけです。新しいパスワードで十分な場合は、現在のパスワードハッシュを履歴セットに移動し、新しいパスワードの新しいハッシュに置き換えます。

22
Martijn Pieters

ユーザーがパスワードを変更するときは、以前のパスワードの入力を要求します。これで、データベースにプレーンテキストのパスワードを保存していなくても、twoプレーンテキストのパスワードにアクセスできます。

これら2つのパスワードに必要な検証をすべて実行します。これは、ユーザーが2つのパスワードを交互に変更することを防止しません(接尾辞付き-他の回答の提案に従って直接変更を防止できます)が、より露骨なケースを防止します。

28
Brian

@martijnPieterの回答に追加するには、新しいパスワードと以前のパスワード(どちらも使用可能)に基づいて短い総当たりを行うことで、最小限の変更を実装できます。

たとえば、新しいパスワードから ハミング距離 1または2のすべてのパスワードを反復処理して、古いパスと一致するかどうかを確認できます

ただし、これにより、パスワードをハッシュしているというユーザーの信頼性が低下する可能性があることに注意してください(基本的に、以前のパスワードを取得して新しいパスワードを拒否することができるため)。

7
ratchet freak

これは、@ Brianの巧妙な答えに対する補遺です。現在のパスワードに基づいて古いパスワードを総当たりする方法の詳細を追加するための@Martijn Pietersと、「ハミング距離」を求める@ratchetフリークへの帽子も。回答をバックアップする興味深い背景が得られると思うので、私の回答は削除しません。

最先端のパスワードストレージでは、ユーザーごとに一意のソルト(128ビット+)を使用した強力な一方向暗号化ハッシュ(SHA-512 +)を複数回使用する必要があります。ただし、各パスワードに関する追加情報を保存するように誘惑されないでください。各パスワードについて保存する情報が多いほど、ハッシュアルゴリズムのセキュリティが損なわれます。

次のことがわかっている場合は、パスワードをブルートフォースにするのがいかに簡単になるかを考えてください。

  • 7文字です
  • 文字3から5は大文字です(4は小文字です)
  • 1と7は数字です
  • 6は記号です

USキーボードには95の印刷可能な文字があるため、パスワードが7文字であることを知っていると、95 ^ 7 = 69,833,729,610,000 = 7x10 ^ 13の順列になります。本当にランダムな場合、単一の3Ghzプロセッサでこれをクラックするのに1年かかる可能性があります。だが:

  • 大文字と小文字は26文字しかありません
  • 10桁しかないため、これらの2つの数値は100の可能性があります
  • シンボルは32個しかありません

だから(@Hellionのおかげで修正されました):

         26^4 (charcters 2-5 are known upper or lower-case)
        x 100 (characters 1 & 7 are digits)
        x  32 (character 6 is a symbol)
         ====
1,462,323,200 possible passwords.

50,000倍簡単にクラックできます!この場合、同様のパスワードを防止するための適切な情報を保存すると、7文字のパスワードを解読するのに1年から数時間かかります。優れたビデオカードと少しの忍耐力を備えた強力なマルチプロセッサデスクトップですべてのパスワードを解読することは、非常に現実的です。この単純な例が、類似したパスワードを比較できるほど意味のあるものになるほど、ハッシュの安全性が低下することを示していると思います。

強力なハッシュの重要性

パスワードが設定されたデータベースは定期的に盗まれ、毎月ニュースが大量に侵入されます。一体、ちょうど先月の状態 SCはみんなの社会保障番号を失った -おっと!これらの違反はさらにいくつ隠されていますか?

おわりに

私にとって最も恐ろしいのは、複数のサイトに同じまたは類似のパスワードを選択して、1つに侵入すると攻撃者がそれらすべてにアクセスできるようになる場合です。最も一般的な不正なパスワードを防止することは、個々のユーザーが同じサイト内で不正なパスワードを再利用することを防止するよりも役立つと思いますが、私はその状況を防止する実証済みの方法を見たいです。私が提案できる最善の方法は、ユーザーごとに非常にランダムなパスワードを生成して安全に保管する安全なパスワードマネージャーを使用するという会社全体のポリシーです。

5
GlenPeterson

最初に、最後の「n」個の以前のパスワードのハッシュを保存できるため、新しいパスワードが以前のパスワードと重複しているかどうかを確認できます。また、現在のパスワード(ログインしたか、パスワード変更要求を認証するためにパスワードを提供したため)のプレーンテキストと新しいパスワードがあるため、これら2つのパスワード間の最小限の変更を確認できます。

これら2つのパスワードを「n」個の以前のパスワードと直接比較することが非常に重要である場合は、後で取得できるようにこれらのパスワードを(暗号化して)保存する必要があります。

これを行うことはセキュリティ上の欠陥と見なすことができますが、十分なセキュリティを提供するために暗号化方法を実装することができます。

  1. 最後の "n"個のパスワードについて、各パスワード(暗号化)を保存します。
  2. 最新のパスワードが作成された日時を保存します。
  3. 最新のパスワードのハッシュを保存します。
  4. 現在のパスワードのハッシュ(ソルト)とパスワード作成タイムスタンプを使用して、すべてのパスワードを暗号化します。アカウント番号や電子メールアドレスなどを暗号化することもできます。
  5. 新しいパスワードが作成されるたびに、すべてのパスワードの暗号化を解除して再暗号化します。

その後、パスワードが変更されるたびに、すべての古いパスワードの暗号化を解除し、最小限の変更テストをすべて実行できます。

さて、誰かがこの人のパスワードを持っていて、他のすべての必要な詳細を知っていれば、彼らはこの人のこの情報の暗号化を解除できます。ただし、このユーザーのパスワードをすでに持っている場合は、このユーザーとしてログインして、このユーザーのアカウントにアクセスできます。

また、古いパスワードの場合は、厳密にプレーンテキストで保存する必要がない場合があります。それらは、難読化された方法で格納できます。または、パスワードの文字のアルファベット順リストとして保存されます。

これが一般的なケースで推奨されることではありませんが、ここで説明したタスクが必要な場合、これはいくつかのセキュリティ対策でこれ​​を達成する1つの方法です。

1
Kevin Fegan