web-dev-qa-db-ja.com

パスワードで暗号化されたユーザー名をキーとして使用することは、優れたパスワードストレージスキームですか?

私が構築するWebアプリケーションでは、パスワードをハッシュしません。代わりに、ユーザーのパスワードを使用してユーザー名を対称的に暗号化し、その結果をパスワードフィールドに格納します。 dotnetでは RijndaelManaged を使用しています。

ログイン時にもう一度やり直し、一致するかどうかを確認します。

私の質問は、ますます多くのデータベースがハッキングされるとき、これは今どれくらい安全ですか?ユーザーの実際のパスワードはいつでもわかりません。ハッカーがdbから取得するのは、未知のパスワードで暗号化されたユーザー名です。ハッシュではレインボーテーブルの問題がありますが、この方法ではそうではありません。

すでに復号化された値(ユーザー名)を知っていると、パスワードを見つけやすくなりますか?

33
Rudy

あなたがすることreallyはハッシュです:あなたはブロック暗号からハッシュ関数を構築しました。ちなみに、「パスワードをキーとする既知の値の暗号化」は、伝統的な NIX向けのDESベースの暗号化スキーム の設計方法です。

プラス面として、構築にはユーザー名が含まれます。これは部分的にソルトの効果を提供します。同じパスワードを使用する2人のユーザーは2つの異なるハッシュ出力になるため、並列クラックは推奨されません。 「部分的に」、なぜならパスワードが変更されてもユーザーは自分のユーザー名を保持するため、ここでは何らかの形の並列処理がまだ可能です。そしておそらくもっと重要なことには、同じユーザー名が複数のWebアプリ(たとえば「admin」)で使用される可能性があります。これにより、事前計算されたテーブルに価値があります(そしてソルトのポイントは並列処理、特に事前計算されたテーブルの効率的な使用を防ぐことです)。

マイナス側:

  • これはhomemade構造です。暗号化に関する50年の研究は、自家製の暗号化が非常にまれであることを教えてくれました。実際、特定のアルゴリズムが他の熟練した研究者による長年のレビューを通じてのみ正しいことを「知る」ことができます。そして、自家製のスキームは、定義上、レビューの多くを得ることはありませんでした。

  • これには制限があります。 Rijndaelは、最大256ビットの鍵を受け入れることができるブロック暗号です。したがって、パスワードをキーとして使用する場合は、256ビット以内に収める必要があります。これにより、強力でありながらエントロピーに多くのスペースを使用することでパスワードを簡単に覚えることができる、いわゆる「パスフレーズ」の使用が防止されます(人間の脳は集中エントロピーは好きではありませんが、希釈エントロピーは満足しています)。

  • これは速すぎる方法であり、thisは、あなたのスキームで最大の当面の問題です。基本的なPCでは、特に最近のPCにはAES用の 専用のオペコード があるため、攻撃者は毎秒多くのパスワードを試すことができます。クアッドコアPCを使用すると、1秒間に最大約5億のパスワードを試すことができます。ユーザーが選択したパスワードの多くは、そのような猛攻撃に長く耐えることができません。

パスワードハッシュの仕組みに興味がある場合は、 this を参照してください。ただし、簡単な答えは同じです。自家製のスキームを使用しないでください。 bcrypt を使用します。

85
Thomas Pornin

他の回答はすでにNo, "roll your own" is rarely a good password storage scheme and yours is no exception.と言っています

追加したい:ユーザー名を保存/伝達するための良いスキームでもありません。
基本的にハッシュしています。それ以外は問題ありません:

  • 安全なハッシュ関数として設計されていない関数を使用しています。暗号であることは確かにスケールの「安全な」終わりにありますが、ハッシュにはハッシュの衝突を回避することも含まれます。暗号は通常、衝突がないように最適化されていません。ワンタイムパッドは、衝突の回数が最大であるため、壊れないことが知られています。したがって、強力な暗号は衝突という点でハッシュを貧弱にします。
  • ユーザー名とユーザー名をパスワードで暗号化して保存すると、さらに多くの脆弱性があります。
    • この場合、データベースがハッキングされても、攻撃者はonly get the username encrypted with an unknown passwordを行いません。彼は別名クリアテキストも取得します。ユーザー名。したがって、これはクリアテキスト分析であり、一部の暗号ではブルートフォースよりもはるかに簡単です。
    • ハッシュの衝突:攻撃者はtheパスワードを知っている必要はありませんが、anyは短い、与えられたクリアテキストに対して同じ暗号化を生成します。これは、平文分析よりも簡単かもしれません。
  • ユーザー名を保存せず、送信された単一の値に依存している場合でも、欠点があります:
    • この場合、おそらくハッシュの衝突を考慮していません。同じユーザー名を持つ2人のユーザーはどうですか?同じユーザー名と同じパスワードを持つ2人の馬鹿はどうですか?純粋な偶然による異なるユーザー名とパスワードのハッシュ衝突についてはどうですか(衝突を回避するために暗号は最適化されていないことに注意してください!)
  • いずれの場合も、「ハッシュを渡す」攻撃があります。ネットワーク通信を盗聴する攻撃者は、アプリケーションをエミュレートしてユーザーと同じデータを渡すことができます。それについて何かしましたか?そうでない場合、それはあなたが「自分でロールする」べきではない理由です。

多くの場合、送信のプロトコルは、ハッシュと暗号化に関係なく、強力な暗号化機能と同じくらいセキュリティにとって重要です。プロトコルが悪いと、関数が不適切な攻撃にさらされる可能性があります。特に、「ハッシュを渡す」や「中間者」などの「サイドチャネル攻撃」は、攻撃者の側で実際の暗号分析を回避します。

ユーザー名もクリアテキストで保存されている場合は、ユーザーが指定しなかったため、パスワードの保存スキームがこのような攻撃を受ける可能性があります。これにより、スキームが上記の攻撃にさらされます。クリアテキストで保存しないと、上記のように攻撃を受けやすい送信プロトコルが必要になる場合があります。

少し一般化された、あなたのケースの伝送プロトコルに関するいくつかの追加の考えは次のとおりです:

「ハッシュを渡す」攻撃について何もしなかった場合、そのスキームは他の多くのスキームよりも悪いです。攻撃者はデータベースをハッキングしたり、暗号を解読したりする必要はありません。ネットワークトラフィックをスニッフィングすることで、必要なものを無料で入手します。

HTTPSで十分かもしれませんが、「中間者」によって回避できます。ユーザーは認証証明書をチェックしていませんね。攻撃者は、認証されていないが暗号化された接続をユーザーと、ユーザーへの予期される接続を開くだけです。

追加のチャレンジ/レスポンス方式により、セキュリティが強化される場合があります。ログインする前に、クライアントは1回限りのランダム文字列(チャレンジ)を受け取ります。これは、ハッシュ(応答)に組み込むために必要です。チャレンジも再利用されないため、攻撃者はスニッフィングされたハッシュを再利用できませんでした。
ただし、「自分でロールする」必要はありません。

11
NoAnswer

TL; DR:scryptを使用します。完全に優れた基準があるのに、なぜ自分でロールするのですか?

(私はscryptがbcryptよりも優れていると考えていますが、bcryptは独自に成長させるよりもはるかに優れています。)

これまでに足りないのはストレッチです。あなたがハッキングされ、データベースがPastebinにダンプされたと想像してください-それは 私たちの中で最高 に起こる可能性があります。

123456または他の上位20のパスワードのいずれかを使用する人々は、あなたが何をしても発見され、それ以上の価値はありません。適度に良いパスワードを選択した人にとって、攻撃者がエントリごとに費やす必要がある時間がマイクロ秒または秒のオーダーである場合、それは違いを生みます。

また、塩漬けではありません。Webアプリケーションの2つがハッキングされ、1人のユーザーが同じユーザー名で同じパスワードのアカウントを両方に持っているとします。攻撃者が両方のダンプで同一の暗号文を取得し、一発一発無料のオファーがあることを彼らに伝えるように思えます。

5
Bristol