86

更新:ソルトとは何か、レインボーテーブルとは何か、辞書攻撃とは何か、ソルトの目的とは何かを尋ねているのではないことに注意してください。私は質問しています:ユーザーがソルトとハッシュを知っている場合、パスワードを計算するのは非常に簡単ではありませんか?

私はプロセスを理解しており、いくつかのプロジェクトで自分で実装しています。

s =  random salt
storedPassword = sha1(password + s)

保存するデータベース:

username | hashed_password | salt

私が見たソルティングのすべての実装は、パスワードの最後または最初にソルトを追加します。

hashed_Password = sha1(s + password )
hashed_Password = sha1(password + s)

したがって、彼のソルト(ha ha)の価値があるハッカーからの辞書攻撃は、上記の一般的な組み合わせで保存されているソルトに対して各キーワードを実行するだけです。

確かに、上記の実装は、根本的な問題を実際に解決することなく、ハッカーに別のステップを追加するだけですか?この問題を回避するための代替手段はありますか、それとも私は問題を誤解していますか?

私が考えることができる唯一のことは、ソルトとパスワードをランダムなパターンで組み合わせたり、ハッシュプロセスに他のユーザーフィールドを追加したりする秘密のブレンドアルゴリズムを使用することです。つまり、ハッカーはデータベースとコードにアクセスして、レースを行う必要があります。実りあることを証明するための辞書攻撃のためにそれらを。(コメントで指摘されているように、更新します。ハッカーがすべての情報にアクセスできると想定するのが最善であるため、これはおそらく最善ではありません)。

ハッカーがパスワードとハッシュのリストを使用してユーザーデータベースをハッキングすることを提案する方法の例を挙げましょう。

ハッキングされたデータベースのデータ:

RawPassword (not stored)  |  Hashed   |     Salt
--------------------------------------------------------
letmein                       WEFLS...       WEFOJFOFO...

一般的なパスワード辞書:

   Common Password
   --------------
   letmein
   12345
   ...

ユーザーレコードごとに、共通のパスワードをループしてハッシュします。

for each user in hacked_DB

    salt = users_salt
    hashed_pw = users_hashed_password

    for each common_password

        testhash = sha1(common_password + salt)
        if testhash = hashed_pw then
           //Match!  Users password = common_password
           //Lets visit the webpage and login now.
        end if

    next

next

これが私の主張をよりよく示していることを願っています。

10,000個の一般的なパスワードと10,000個のユーザーレコードがある場合、できるだけ多くのユーザーパスワードを検出するには、1億回のハッシュを計算する必要があります。数時間かかる場合がありますが、実際には問題ではありません。

クラッキング理論に関する最新情報

私たちは破損したウェブホストであり、SHA1ハッシュとソルトのデータベースにアクセスし、それらをブレンドするためのアルゴリズムを持っていると想定します。データベースには10,000のユーザーレコードがあります。

このサイトは、GPUを使用して1秒あたり2,300,000,000のSHA1ハッシュを計算できると主張しています。(実際の状況ではおそらく遅くなりますが、今のところはその引用された図を使用します)。

(((95 ^ 4)/ 2300000000)/ 2)* 10000=177秒

最大長が4文字の95個の印刷可能なASCII文字の全範囲を、計算速度(可変)で割った値を2で割った値(パスワードを検出するための平均時間が平均して50%の順列を必要とすると仮定)の場合、10,000ユーザーは、長さが4未満のすべてのユーザーのパスワードを計算するのに177秒かかります。

リアリズムのために少し調整してみましょう。

(((36 ^ 7)/ 1000000000)/ 2)* 10000=2日

大文字と小文字を区別せず、パスワードの長さが7文字未満で、英数字のみを使用すると、10,000ユーザーレコードを解決するのに4日かかります。また、オーバーヘッドと非理想的な状況を反映するために、アルゴリズムの速度を半分にしました。

これは線形ブルートフォース攻撃であることを認識することが重要です。すべての計算は互いに独立しているため、複数のシステムで解決するのに最適なタスクです。(つまり、実行時間の半分になる異なる端から攻撃を実行する2台のコンピューターを簡単にセットアップできます)。

このタスクをより計算コストの高いものにするために、パスワードを1,000回再帰的にハッシュする場合を考えると、次のようになります。

(((36 ^ 7)/ 1 000 000 000)/ 2)*1000秒=10.8839117時間

これは、 1人のユーザーの引用符で囲まれた数値から半分以下の速度で実行される最大7文字の英数字を表します。

1,000回の再帰的なハッシュは、包括的攻撃を効果的にブロックしますが、ユーザーデータに対する標的型攻撃は依然として脆弱です。

4

11 に答える 11

62

辞書攻撃を止めることはできません。

それが行うことは、パスワードファイルのコピーを取得することに成功した誰かがレインボーテーブルを使用してハッシュからパスワードが何であるかを理解するのを阻止することです。

ただし、最終的にはブルートフォース攻撃を受ける可能性があります。その部分への答えは、ユーザーに辞書の単語をパスワードとして使用しないように強制することです(たとえば、少なくとも1つの数字または特殊文字の最小要件)。

更新

これについては前に説明したはずですが、一部の(ほとんどの?)パスワードシステムは、パスワードごとに異なるソルトを使用し、パスワード自体と一緒に保存されている可能性があります。これにより、1つのレインボーテーブルが役に立たなくなります。これがUNIX暗号化ライブラリの仕組みであり、最新のUNIXライクなOSは、このライブラリを新しいハッシュアルゴリズムで拡張しました。

新しいバージョンのGNUcryptでSHA-256とSHA-512のサポートが追加されたことを知っています。

于 2010-08-25T13:57:37.220 に答える
32

より正確には、辞書攻撃、つまり網羅的なリスト内のすべての単語が試行される攻撃は「不可能」ではありませんが、実用的ではありません。ソルトの各ビットは、必要なストレージと計算の量を2倍にします。

これは、ソルトが秘密であるかどうかに関係なく、レインボーテーブルを含む攻撃のような事前に計算された辞書攻撃とは異なります。

例: 64ビットソルト(つまり8バイト)では、辞書攻撃で264の追加のパスワードの組み合わせをチェックする必要があります。200,000語を含む辞書を使用すると、作成する必要があります

200,000 * 2 64 = 3.69 * 10 24

最悪の場合のテスト-ソルトなしの200,000テストの代わりに。

ソルトを使用することの追加の利点は、攻撃者が自分の辞書からパスワードハッシュを事前に計算できないことです。時間やスペースがかかりすぎるだけです。

アップデート

あなたのアップデートは、攻撃者がすでにソルトを知っている(またはそれを盗んだ)ことを前提としています。もちろん、これは別の状況です。それでも、攻撃者が事前に計算されたレインボーテーブルを使用することはできません。ここで非常に重要なのは、ハッシュ関数の速度です。攻撃を非現実的にするには、ハッシュ関数を遅くする必要があります。MD5またはSHAは高速になるように設計されているため、ここでは適切な候補ではありません。ハッシュアルゴリズムのより適切な候補は、Blowfishまたはそのバリエーションです。

アップデート2

一般的にパスワードハッシュを保護することについての良い読み物(元の質問をはるかに超えていますが、それでも興味深いです):

レインボーテーブルで十分:安全なパスワードスキームについて知っておくべきこと

記事の結果:bcrypt(Blowfishに基づく)またはEksblowfishで作成されたソルトハッシュを使用して、構成可能なセットアップ時間を使用してハッシュを遅くすることができます。

于 2010-08-25T13:54:58.447 に答える
31

はい、sha1(salt | password)に必要な日数はわずか3日です。そのため、優れたパスワードストレージアルゴリズムは1000回の反復ハッシュを使用します。8年かかるでしょう。

于 2010-08-25T15:00:29.747 に答える
17

ディクショナリは、値がキーによってインデックス付けされる構造です。事前に計算された辞書攻撃の場合、各キーはハッシュであり、対応する値はハッシュになるパスワードです。事前に計算された辞書が手元にあると、攻撃者はログインに必要なハッシュを生成するパスワードを「即座に」検索できます。

ソルトを使用すると、辞書を保存するために必要なスペースが急速に増大します…非常に急速に、パスワード辞書を事前に計算しようとしてもすぐに無意味になります。

最高の塩は、暗号化乱数ジェネレーターからランダムに選択されます。8バイトは実用的なサイズであり、16バイトを超えると目的がありません。


Saltは、「攻撃者の仕事をより苛立たせる」だけではありません。事前に計算された辞書の使用という、あらゆる種類の攻撃を排除します。

パスワードを完全に保護するには、もう1つの要素が必要です。それは、「キー強化」です。SHA-1の1ラウンドでは不十分です。安全なパスワードハッシュアルゴリズムは、計算が非常に遅くなるはずです。

多くの人が、結果をハッシュ関数に何千回もフィードバックする鍵導出関数であるPBKDF2を使用しています。「bcrypt」アルゴリズムも同様で、低速の反復鍵導出を使用します。

ハッシュ操作が非常に遅い場合、事前に計算されたテーブルが攻撃者にとってますます望ましいものになります。しかし、適切な塩はそのアプローチを打ち負かします。


コメントコメント

以下は私が質問に対してしたコメントです。


ソルトがなければ、攻撃者は「アップデート2」で示されている方法を使用しません。彼は、事前に計算されたテーブルでルックアップを実行し、O(1)またはO(log n)時間(nは候補パスワードの数)でパスワードを取得するだけです。ソルトはそれを防ぎ、「アップデート2」に示されているO(n)アプローチを使用するように彼に強制します。

O(n)攻撃に減少したら、各試行にかかる時間を考慮する必要があります。キー強化により、ループ内の各試行に1秒かかる可能性があります。つまり、1万人のユーザーで1万人のパスワードをテストするのに必要な時間は、3日から3に延長されます。その時のパスワード。

攻撃者はPHPではなく、可能な限り最速のツールを使用することを考慮する必要があります。そのため、100回ではなく数千回の反復が、キー強化の適切なパラメーターになります。単一のパスワードのハッシュを計算するには、1秒の大部分が必要です。

キー強化は、PKCS#5の標準キー派生アルゴリズムPBKDF1およびPBKDF2の一部であり、優れたパスワード難読化アルゴリズムを作成します(「派生キー」は「ハッシュ」です)。

StackOverflowの多くのユーザーは、レインボーテーブルの危険性に関するJeff Atwoodの投稿への回答であるため、この記事を参照しています。これは私のお気に入りの記事ではありませんが、これらの概念について詳しく説明しています。


もちろん、攻撃者はソルト、ハッシュ、ユーザー名などすべてを持っていると想定します。攻撃者がmyprettypony.comファンサイトにユーザーテーブルをダンプした破損したホスティング会社の従業員であると想定します。彼は振り返って、ポニーファンがcitibank.comアカウントで同じパスワードを使用しているかどうかを確認するため、これらのパスワードを回復しようとしています。

適切に設計されたパスワードスキームでは、この男がパスワードを回復することは不可能です。

于 2010-08-25T13:57:36.083 に答える
7

塩漬けのポイントは、攻撃者の努力の償却を防ぐことです。

ソルトなしで、事前に計算されたハッシュパスワードエントリの単一のテーブル(たとえば、すべての英数字の5文字列のMD5、オンラインで簡単に見つけることができます)は、世界中のすべてのデータベースのすべてのユーザーで使用できます。

サイト固有のソルトを使用すると、攻撃者は自分でテーブルを計算し、サイトのすべてのユーザーでそれを使用できるようにする必要があります。

ユーザーごとのソルトを使用すると、攻撃者はこの作業をすべてのユーザーに個別に費やす必要があります。

もちろん、これは辞書から直接非常に弱いパスワードを保護するのにあまり効果がありませんが、この償却からかなり強いパスワードを保護します。

于 2010-08-25T15:15:35.150 に答える
6

また、もう1つの重要な点として、USER固有のソルトを使用すると、同じパスワードを持つ2人のユーザーが検出されなくなります。ハッシュは一致します。そのため、多くの場合、ハッシュはハッシュ(ソルト+ユーザー名+パスワード)です。

ハッシュを秘密にしておこうとすると、攻撃者はハッシュを検証することもできません。

編集-上記のコメントで要点が述べられていることに気づきました。

于 2010-08-25T19:22:27.663 に答える
5

レインボーテーブル攻撃を防ぐためにソルトが実装されています。レインボーテーブルは、事前に計算されたハッシュのリストであり、ハッシュをそのフレーズに変換するのがはるかに簡単になります。最新のハッシュアルゴリズムがない限り、ソルティングはパスワードの解読に対する最新の防止策としては効果的ではないことを理解する必要があります。

つまり、このアルゴで発見された最近のエクスプロイトを利用してSHA1を使用しているとしましょう。また、コンピューターが1,000,000ハッシュ/秒で実行されているとすると、衝突を見つけるのに530万年かかるとしましょう。 300秒で動作することができます、大きなウープ、実際には問題ではありません。私たちが塩漬けにする理由は、誰かがわざわざすべての一般的な辞書フレーズを生成した場合(2 ^ 160人、2007年のエクスプロイトへようこそ)です。

これが実際のデータベースで、テストと管理の目的で2人のユーザーを使用しています。

RegistrationTime        UserName        UserPass    
1280185359.365591       briang      a50b63e927b3aebfc20cd783e0fc5321b0e5e8b5
1281546174.065087       test        5872548f2abfef8cb729cac14bc979462798d023

実際、ソルティングスキームはsha1(登録時間+ユーザー名)です。どうぞ、私のパスワードを教えてください。これらは本番環境での実際のパスワードです。そこに座って、phpで単語リストをハッシュ化することもできます。ワイルドになります。

私は頭がおかしいわけではありません。これが安全であることを知っています。楽しみのために、testのパスワードはtestです。 sha1(sha1(1281546174.065087 + test) + test) = 5872548f2abfef8cb729cac14bc979462798d023

このユーザーだけ27662aee8eee1cb5ab4917b09bdba31d091ab732のために、レインボーテーブル全体を生成する必要があります。つまり、実際には、単一のレインボーテーブルによってすべてのパスワードが危険にさらされることはありません。ハッカーは、テスト用に27662aee8eee1cb5ab4917b09bdba31d091ab732用にレインボーテーブル全体を生成し、briang用にf3f7735311217529f2e020468004a2aa5b3dee7fを生成する必要があります。すべてのハッシュについて、530万年を振り返ってみてください。2 ^ 80のハッシュ(20ヨタバイトをはるかに超える)だけを格納するサイズを考えてみてください。そうなることはありません。

ハッシュをデコードできないものにする手段としてソルティングを混同しないでください。これは、レインボーテーブルがすべてのユーザーパスワードを変換するのを防ぐ手段です。このレベルのテクノロジーでは不可能です。

于 2010-08-25T17:40:59.360 に答える
3

辞書攻撃の背後にある考え方は、ハッシュを取得し、ハッシュを計算せずに、このハッシュが計算されたパスワードを見つけることです。塩漬けのパスワードでも同じことをします-できません。

ソルトを使用しないと、データベースでの検索と同じくらい簡単にパスワードを検索できます。ソルトを追加すると、攻撃者は考えられるすべてのパスワードのハッシュ計算を実行します(辞書に添付されている場合でも、これにより攻撃時間が大幅に増加します)。

于 2010-08-25T13:55:24.853 に答える
2

簡単に言うと、ソルトなしで、各候補パスワードを1回ハッシュするだけで、同じアルゴリズムを介してパスワードがハッシュされる「既知の宇宙」(侵害されたデータベースのコレクション)内のすべてのユーザーに対してパスワードをチェックできます。ソルトでは、可能なソルト値の数が「既知のユニバース」のユーザー数を大幅に超える場合、テスト対象のユーザーごとに各候補パスワードを個別にハッシュする必要があります。

于 2010-08-25T15:04:37.807 に答える
2

簡単に言えば、ソルティングはハッシュ(ブルートフォースまたは辞書)の攻撃を防ぐことはできず、それを難し​​くするだけです。攻撃者は、ソルティングアルゴリズム(適切に実装された場合、より多くの反復を使用する)を見つけるか、アルゴをブルートフォースする必要があります。これは、非常に単純でない限り、ほぼ不可能です。ソルトはまた、レインボーテーブルルックアップのオプションをほぼ完全に破棄します...

于 2010-11-18T17:55:44.147 に答える
1

ソルトは、単一のパスワードハッシュを解読するのをはるかに困難にするため、レインボーテーブル攻撃をはるかに困難にします。番号1だけの恐ろしいパスワードを持っていると想像してください。レインボーテーブル攻撃はこれをすぐにクラックします。

ここで、データベース内の各パスワードが、多くのランダムな文字の長いランダムな値でソルトされていると想像してください。これで、お粗末なパスワード「1」が1のハッシュとランダムな文字(ソルト)の束としてデータベースに保存されるため、この例では、レインボーテーブルに次のようなハッシュが必要です。

したがって、ソルトが安全でランダムなものであると仮定すると、たとえば()%ISLDGHASKLU(%#%#、ハッカーのレインボーテーブルには1 *()%ISLDGHASKLU(*%#%#)のエントリが必要になります。レインボーテーブルを使用します。この単純なパスワードでさえ、もはや実用的ではありません。

于 2010-08-25T14:01:29.753 に答える