現在、所有している Web アプリのプレーン テキスト パスワードを保存しています。
私はパスワード ハッシュへの移行を主張し続けていますが、別の開発者は、これは安全性が低くなると言いました。より多くのパスワードがハッシュに一致する可能性があり、辞書/ハッシュ攻撃がより高速になります。
この議論に真実はありますか?
現在、所有している Web アプリのプレーン テキスト パスワードを保存しています。
私はパスワード ハッシュへの移行を主張し続けていますが、別の開発者は、これは安全性が低くなると言いました。より多くのパスワードがハッシュに一致する可能性があり、辞書/ハッシュ攻撃がより高速になります。
この議論に真実はありますか?
絶対にありません。しかし、それは問題ではありません。私は以前に同様の応答を投稿しました:
残念なことですが、人々は、たとえプログラマーであっても、感情的になりすぎて、簡単に議論に左右されることはありません。彼が自分の立場に投資したら (そして、あなたがここに投稿しているなら、彼はそうです)、事実だけで彼を納得させることはまずありません。あなたがする必要があるのは、立証責任を切り替えることです。彼があなたを納得させることを望んでいるデータを探しに彼を連れ出す必要があり、そうすることで真実を学ぶ必要があります. 残念ながら、彼は現状維持の恩恵を受けているので、そこまでの道のりは険しいです。
ウィキペディアより
一部のコンピューター システムでは、ユーザーのログオン試行を比較するためのユーザー パスワードを平文として保存します。攻撃者がこのような内部パスワード ストアへのアクセスを取得すると、すべてのパスワードとすべてのユーザー アカウントが危険にさらされます。一部のユーザーが異なるシステムのアカウントに同じパスワードを使用すると、それらも侵害されます。
より安全なシステムでは、各パスワードが暗号で保護された形式で保存されるため、システムへの内部アクセスを取得したスヌーパーが実際のパスワードにアクセスすることは依然として困難ですが、ユーザー アクセス試行の検証は可能です。
一般的なアプローチでは、平文パスワードの「ハッシュ」形式のみを保存します。このようなシステムでユーザーがパスワードを入力すると、パスワード処理ソフトウェアが暗号化ハッシュ アルゴリズムを実行し、ユーザーのエントリから生成されたハッシュ値がパスワード データベースに格納されているハッシュと一致する場合、ユーザーはアクセスを許可されます。ハッシュ値は、送信されたパスワードと、通常はソルトと呼ばれる別の値で構成される文字列に暗号化ハッシュ関数を適用することによって作成されます。ソルトは、攻撃者が一般的なパスワードのハッシュ値のリストを作成するのを防ぎます。MD5 と SHA1 は、頻繁に使用される暗号化ハッシュ関数です。
そのページの主題について読むことができるものは他にもたくさんあります。私の意見では、そして私が読んで作業したすべてのことにおいて、非常に小さな (< 256 ビット) アルゴリズムを使用しない限り、ハッシュはより良いシナリオです。
Web アプリで平文のパスワードを保持する言い訳は絶対にありません。標準ハッシュ アルゴリズム (MD5 ではなく SHA-1!) をソルト値と共に使用して、レインボー アタックを不可能にします。
パスワードをソルトしないと、レインボー テーブル攻撃 (特定のハッシュに対して有効な入力を持つプリコンパイル済み辞書) の疑いがあります。
パスワードをプレーンテキストで保存している場合、他の開発者はセキュリティについて話すのをやめて、セキュリティについて読み始める必要があります。
衝突は発生する可能性がありますが、通常、パスワード アプリでは大きな問題にはなりません (主に、ファイルの整合性を検証する方法としてハッシュが使用される領域で問題になります)。
そのため、パスワードをソルト化し (パスワードの右側にソルトを追加する*)、SHA-1 またはできれば SHA-256 または SHA-512 などの優れたハッシュ アルゴリズムを使用します。
PS:ここでハッシュについてもう少し詳しく説明します。
*Salt を文字列の先頭または末尾に配置する必要があるかどうかは、少しわかりません。問題は、衝突 (同じハッシュを持つ 2 つの入力) がある場合、Salt を「間違った」側に追加しても、結果のハッシュが変更されないことです。いずれにしても、Rainbow Tables では大きな問題は発生せず、衝突のみが発生します。
あなたの他の開発者が「より多くのパスワードがハッシュに一致する可能性がある」ということを理解していません。
「ハッシュ攻撃の方が速い」という議論がありますが、パスワードがハッシュされているときにソルトしていない場合に限ります。通常、ハッシュ関数を使用すると、既知のハッシュ テーブルを使用するのが時間の無駄になるソルトを提供できます。
個人的には、「いいえ」と言います。上記に基づいて、また、何らかの方法でクリアテキストの公開を取得した場合、ソルト化されたハッシュ値は、侵入しようとする誰かにとってほとんど価値がないという事実に基づいています。ハッシングは、すべてのパスワードを同じ長さ。
つまり、任意の文字列をハッシュすると常に 20 文字のハッシュが得られる場合、ハッシュのみを確認すると、たとえば元のパスワードが 8 文字だったのか 16 文字だったのかわかりません。
職場でこれとまったく同じ問題が発生しました。ハッシュがより安全であることを彼に納得させるために私がしたことは、私たちのサイトのパブリック セクションからユーザーとパスワードのリストを返す SQL インジェクションを作成することでした。重大なセキュリティ問題としてすぐにエスカレートされました:)
辞書/ハッシュ攻撃を防ぐには、各ユーザーに固有で静的なトークンに対してハッシュするようにしてください (ユーザー名/参加日/ユーザーガイドは適切に機能します)。
暗号学者のふりをしているプログラマーについての古いことわざがあります:)
Jeff Atwood がこの件に関して良い記事を書いています:
より広範囲に返信するには、上記のすべてに同意します。複数のパスワードが同じハッシュに一致するため、理論的にはハッシュを使用するとユーザーのパスワードを簡単に取得できます。ただし、誰かがデータベースにアクセスするよりも、これが発生する可能性ははるかに低くなります。
何かをハッシュすると、衝突が発生するため、2 つの異なるパスワードが同じアカウントのロックを解除する可能性があるというのは真実です。
ただし、実用的な観点からは、これは不十分な議論です。優れたハッシュ関数 (md5 または sha1 で問題ありません) は、意味のあるすべての文字列、特に短い文字列について、衝突が発生しないことをほぼ保証できます。あったとしても、1 つのアカウントに対して 2 つのパスワードが一致することは大きな問題ではありません。だれかがパスワードをランダムに推測して、侵入できる可能性が高い場合は、より大きな問題が発生します。
パスワードをプレーン テキストで保存することは、パスワード マッチングでのハッシュの衝突よりもはるかに大きなセキュリティ リスクを表すと私は主張します。
プレーンテキストのパスワードを保存することほど安全なものはありません。適切なハッシュアルゴリズムを使用している場合(少なくともSHA-256ですが、SHA-1でも何もないよりはましです)、はい、衝突は可能ですが、ハッシュが与えられているため、何を計算することは不可能です*。文字列はそれにハッシュします。ユーザー名をパスワードでハッシュすると、その可能性もウィンドウの外に出ます。
*-技術的には不可能ではありませんが、「計算上実行不可能」です
ユーザー名が「graeme」でパスワードが「stackoverflow」の場合、文字列「graeme-stackoverflow-1234」を作成します。1234は乱数で、ハッシュして「hashoutput1234」をデータベースに保存します。パスワードの検証に関しては、ユーザー名、提供されたパスワード、および保存された値の末尾からの番号(ハッシュは固定長であるため、いつでも実行できます)を取得し、それらを一緒にハッシュして、ハッシュと比較します。保存された値の一部。
私はセキュリティの専門家ではありませんが、プレーン テキストがより安全であれば、ハッシュ化はそもそも存在しないだろうと感じています。
理論的には、そうです。パスワードはハッシュよりも長く (情報が多く) なる可能性があるため、ハッシュの競合が発生する可能性があります。ただし、ほとんどの攻撃は辞書ベースであり、衝突の可能性は、成功した直接一致よりもはるかに小さくなります。
何を防御するかによります。攻撃者がデータベースをダウンさせる (またはアプリケーションをだましてデータベースを表示させる) 場合、プレーンテキストのパスワードは役に立ちません。SQL インジェクション、セッション ハイジャックなど、アプリケーションにプライベート データを破棄させることに依存する多くの攻撃があります。データをまったく保持しない方がよい場合がよくありますが、悪者が簡単に使用できないようにハッシュ バージョンを保持することをお勧めします。 .
あなたの同僚が示唆しているように、辞書に対して同じハッシュ アルゴリズムを実行し、レインボー テーブルを使用して情報を引き出すことで、これを簡単に無効にすることができます。通常の解決策は、秘密のソルトと追加のユーザー情報を使用して、ハッシュされた結果を一意にすることです。次のようになります。
String hashedPass=CryptUtils.MD5("alsdl;ksahglhkjfsdkjhkjhkfsdlsdf" + user.getCreateDate().toString() + user.getPassword);
ソルトが秘密である限り、または攻撃者がユーザー レコードの正確な作成日を知らない限り、パスワード フィールドをプルダウンできたとしても、辞書攻撃は失敗します。
クライアント側の JavaScript を使用して、送信前にパスワードをハッシュするという、私が書いた解決策をプラグインしたことをお許しください: http://blog.asgeirnilsen.com/2005/11/password-authentication-without.html
より多くのパスワードがハッシュに一致する可能性があり、辞書/ハッシュ攻撃がより高速になります。
はいといいえ。SHA バリアントのような最新のハッシュ アルゴリズムを使用すると、その引数は非常に長くなります。そのブルート フォース攻撃が 467 年ではなく 352 年しかかからないとしたら、本当に心配する必要がありますか? (逸話的なジョークです。) 得られる価値 (パスワードをシステムに平文で保存しないこと) は、同僚の懸念をはるかに上回ります。