1. ホーム
  2. security

[解決済み] なぜ塩を使うと辞書攻撃が「不可能」になるのか?

2023-05-22 11:43:30

疑問点

更新:私はソルトとは何か、レインボーテーブルとは何か、辞書攻撃とは何か、ソルトの目的は何かを尋ねているのではないことに注意してください。私はクエリしているのです。ユーザーのソルトとハッシュを知っていれば、パスワードを計算するのは非常に簡単ではないでしょうか?

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

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

保存するデータベースで

username | hashed_password | salt

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

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

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

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

私が考えられる唯一のことは、塩とパスワードをランダムなパターンで一緒に混ぜる秘密の混合アルゴリズムを持っているか、ハッシュ処理に他のユーザー フィールドを追加して、ハッカーがデータベースとコードにアクセスして、辞書攻撃が実を結ぶことを証明する必要があることを意味します。(コメントで指摘されたように、ハッカーがすべての情報にアクセスできると仮定するのが最善なので、これはおそらく最善ではありません)。

私が提案する、ハッカーがパスワードとハッシュのリストを持つユーザー データベースをハックする方法の例を挙げてみましょう。

ハッキングされたデータベースのデータです。

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 のユーザー レコードがある場合、できるだけ多くのユーザー パスワードを発見するために 100,000,000 個のハッシュを計算する必要があります。 数時間かかるかもしれませんが、それは本当に問題ではありません。

クラッキング理論に関する更新

私たちは、SHA1 ハッシュとソルト、およびそれらをブレンドするアルゴリズムを含むデータベースにアクセスできる、破損したウェブホストであると仮定します。 データベースは 10,000 人のユーザー レコードを持ちます。

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

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

95 の印刷可能な ASCII 文字の全範囲が与えられ、最大長は 4 文字で、計算速度 (変数) で割ると、1 万人のユーザーに対して 2 で割った値 (パスワードを発見する平均時間は、平均して順列の 50% を必要とすると仮定) となり、すべてのユーザーのパスワードの長さが <= 4 である場合に計算するには 177 秒かかることになります。

現実的に考えて、これを少し調整してみましょう。

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

大文字と小文字を区別しないと仮定すると、パスワードの長さが 7、英数字のみ、1 万人のユーザー レコードを解くのに 4 日かかることになります。

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

このタスクをより計算高くするために、パスワードを 1,000 回再帰的にハッシュ化する場合を考えてみましょう。

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

の見積もりから半分以下の速度で実行され、最大7文字の英数字を表現しています。 1ユーザー .

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

どのように解決するのか?

はい、sha1(salt | password)でちょうど3日必要です。そのため、良いパスワード保存アルゴリズムは1000回繰り返しのハッシュを使用します:あなたは8年必要とします。