web-dev-qa-db-ja.com

ランダムパスワードに対してソルトなしのハッシュは安全ですか?

トークン認証でAPIを設計しています。

トークンをプレーンテキストとしてデータベースに保存したくないのは、ユーザーパスワードがプレーンテキストとして保存されないのと同じ理由です。データベースが危険にさらされた場合、攻撃者は使用可能なトークンをデータベースから抽出できません。

私の現在の計画は、次のように構成された長さ40文字のトークンを生成することです。

  • 最初の20文字はトークン "ID"(データベースの主キー)になります
  • 次の20文字はトークン「パスワード」になります

トークンを生成したら、完全なトークンをクライアントに送信し、データベースに保存します。

  • トークンID
  • トークンパスワードのSHA1ハッシュ

このようにして、私のデータベースはクライアントに送信された実際のトークンの半分のみを保持し、トークンの確認のみを行い、取得はできません。

saltを追加するつもりはありません:理解できるように、saltの重要な点は、ハッシュテーブル/レインボーテーブルの攻撃を防ぐことです。完全にランダム、十分なエントロピー(67文字、20文字の長さ= 4×10)36 組み合わせ)。何かを見落とさない限り、この場合にソルトを追加することは、長いランダムパスワードを作成することと同じです。

また、Bcryptなどの高額なハッシュテクニックを使用する予定はありません、高すぎるため、ユーザー認証とは異なり、ユーザーが一度認証を行ってからセッションIDを取得すると、トークンはここでの唯一の認証方法であり、すべてのAPI呼び出しで送信されます。ここでは50msのハッシュ方式は受け入れられません。前のポイントで公開したのと同じ理由で、高価なハッシュテクニックを特に安全にすることは考えていません。パスワードは十分なエントロピーでランダムであるため、強力なハッシュマシンを使用しても、総当たり攻撃には数十億年かかります。

私のアプローチに欠陥はありますか?

私が考えることができる唯一のものは(誰かがデータベースにアクセスできることを前提として!)、SHA1に脆弱性が見つかった場合であり、特定のハッシュを出力として与える入力を見つけることが可能になります(これはどういうわけかMD5に起こりました、私は聞いた)。しかし、これは、そこにあるすべてのハッシュアルゴリズムで同じことだと思います。

2
Benjamin

このような目的で暗号化ハッシュ関数を使用するのは日常的なことです。関連するプロパティはプリイメージ耐性と呼ばれます。関数Hの場合、任意のxが指定されたy = H(x)のようなyを見つけることはできません。

(SHA-1でも、耐衝突性はありませんが、この特性があります。ただし、SHA-2のような他のものを使用する必要があります。)

プリイメージ耐性は、ハッシュ関数を一方向にするものの一部です。ハッシュされたパスワードに対する最善の攻撃は、推測とチェックです。 512ビットのハッシュに対して完全に情報のない推測を行う場合、有効なxを推測する確率は2です。-512。成功するまでに予想される推測の数は想像を絶するほど大きくなります。

ハッシュからパスワードを回復する場合、一般的なユーザーのパスワードを推測することはほとんどありません。パスワードクラッカーは、人間が選択するパスワードの種類をよく理解しています。もっともらしい候補パスワードのチェックを優先するため、成功します。

誰かが非現実的な強力なパスワードを持っている場合、クラッカーが無知の推測を行っているかのように、パスワードクラッキングの試みが失敗することはほぼ確実です。しかし、ユーザーは十分に強力なパスワードを選択しないため、開発者は専用のパスワードハッシュアルゴリズムを選択する必要があります。これらのアルゴリズムの目標は、候補パスワードのテストプロセスをより高価にすることです。 (今日、人々はArgon2idを使用する必要があります。これは高価であり、一般的なハードウェアでは比較的効率的であり、bcryptまたはPBKDF2よりも並列化が困難です。)

すべての人が十分に予測できないパスワードを使用した場合、高価なハッシュアルゴリズムは不要または有用ではなくなります。各パスワードが一意であり、再利用されない場合は、ソルトも必要ありません。 (ただし、通常のパスワードにはさまざまな理由でソルトが必要です。)

「パスワード」を制御する場合、これらの値が十分に予測不可能であることを確認できます。 (その時点で、それを「キー」と呼ぶこともできます。)ハッシュ関数がプリイメージ耐性があり、入力がそれぞれ十分に予測不可能である限り、たとえハッシュのテーブルが取得しても、古い(安全な)ハッシュは安全です。漏れた。

ハッシュがリークされるかどうかは問題ではないため、主キーとして使用するために別のIDは必要ありません。パスワードのハッシュ自体を主キーとして使用できます。

(ユーザーが選択したパスワードに対してこれを実行することは望ましくありません。サイドチャネル(データベースルックアップに基づくタイミング攻撃など)はハッシュ出力をリークする可能性があり、オフラインパスワードの解読を可能にする可能性があります。)

各トークンのエントロピーが十分に大きい場合(256ビットは間違いなく安全です。「誕生日のパラドックス」を参照)、各トークンが一意であることを確認できます。同様に、ハッシュ関数の出力が十分に大きい場合、個別の(実際の)入力は個別のハッシュ出力になります。したがって、40文字のトークンを生成し、ユーザーにトークンを渡して、64バイトのハッシュを(アカウントID、有効期限、またはその他の関連情報とともに)データベースに保存しても問題ありません。

2
Future Security