(これはソルトとパスワードの違いについての詳細なので、リンクされた質問IMHOの複製ではありません。両方の変数はハッシュの生成に使用されます)
攻撃者がパスワードをbcryptでハッシュ化したデータベースにオフラインでアクセスするとします(ペッパーは追加されていません)。ハッシュは次のようになります。
$2y$10$H0mRpD2XJZDguAzxTehwzunRkjUR8lB3O4UGrAGLiqJuvnlWjFA7G
塩は次のとおりです:H0mRpD2XJZDguAzxTehwzu
およびハッシュはnRkjUR8lB3O4UGrAGLiqJuvnlWjFA7G
。
攻撃者は、レインボーテーブルを実行してハッシュを照合することはできませんが、含まれているソルトを使用して一般的なパスワードを計算する可能性があるため、次を実行します。
bcrypt("abcd1234", 10, "H0mRpD2XJZDguAzxTehwzu")
生成されます:
nRkjUR8lB3O4UGrAGLiqJuvnlWjFA7G
そして、そこにあります!彼女はすべてのデータベーステスト「abcd1234」を実行し、どのユーザーがその弱いパスワードを数秒/分で使用しているかを特定できます。
では、ハッシュのみの場合はnRkjUR8lB3O4UGrAGLiqJuvnlWjFA7G
はデータベースに保存されていますか(塩分なし)?
攻撃者がユーザー "abcdefg"がパスワード "abcd1234"を使用している可能性があると強く感じている場合、どのようにして彼女の理論をオフラインでテストできますか?彼女は塩を推測する必要があります。どうすれば彼女はそれを行うことができますか?それぞれの組み合わせを試すより簡単な方法はありますか?たぶんその特定のケースでは、それを試す十分な動機がないでしょう。しかし、システムがすべてのパスワードに同じソルトを使用していると彼女が疑う場合はどうなりますか(一部のハッシュは同じであるため)。彼女がそれを解読するのはどれほど難しいでしょうか?
[〜#〜]更新[〜#〜]
ペレウスの答えは私が期待していたものに近い。私はそれを拡張しようとします(私が間違っている場合は修正してください):
エントロピー:
Bcryptでは通常、ソルトはランダムな16バイト(128ビット)です。これを同じ長さのパスワードと比較すると、通常、パスワードはユーザーがキーボードで入力できるものに制限されるため、ソルトにはパスワードよりも大きなエントロピーがあります。
これらの16バイトは(Base64を使用して)HEXにエンコードされ、22の長さになります。それらを22文字のパスワードと比較すると、パスワードにはより大きなエントロピーが含まれます(記号と完全なアルファベットを含めることができるため)。
長さ:
Bcryptソルトは16バイトに制限されていますが、パスワードは実装に応じて72バイトに制限される場合があります。
衝突:
2つの異なるsaltは2つの異なるハッシュを生成するため、パスワードも生成されます。ただし、ある時点で、2つの異なるソルトが同じパスワードを使用して同じハッシュを生成したり、その逆の場合があります。それらの各ケースの確率はどれですか?それは多分私がcrypto.SEで尋ねるべきものです。しかし、誰かが答えを持っている場合に備えて、ここに置いておきます。
デザイン:
このアルゴリズムは、ソルトではなくパスワードを保護するように設計されています。これは、塩が意図的に安全であることを意味するものではないことを意味します。これは、それらを総当たりすることなくそれらを取得する方法が潜在的にあり得ることを示唆しています。
架空のケース:
システムへのアクセスを保護するために、ユーザーパスワードを使用する方法に慣れています。しかし、what ifこのようなことが起こります(私に裸にしてください、その単なる例です)?:
会社CauseWeWantItThatWay
はマイクロチップを使用して、一意の22桁の16進数の値を格納します(塩として使用されます)。各ユーザーは、合計5つのパスワードまたはPIN番号(各4桁、それぞれ、怠惰です)を生成し、その固有のソルトで5つの異なるシステムにアクセスします。
ここで、これらのシステムの1つに割り当てられていて、それらのPIN=番号の1つを知っていて、どういうわけかデータベースにアクセスできると仮定します。saltが含まれている場合、それは簡単です。これらのPIN=数値を取得しますが、塩がなければ、解読する必要があります。
私はあなたが何を考えているのか知っています。同社のセキュリティ実装は非常に悪い(そして、彼らは地獄で燃え上がるはずだ)。また、代わりにコショウとして「塩」を使用し、塩をランダムにしておくこともできます。だから私の質問は、その場合、塩として使用するよりも、22ヘクタールをコショウとして追加することは同じでしょうか?ペレウスによると、それは同じです(そのため、塩を取得するためのショートカットはありません)。
結局のところ、誰もが推奨事項に従うわけではなく、アルゴリズムによってソルトを設定できるため、この種のシナリオは完全に可能になります(それほど可能性も推奨もされていません)。
塩の目的を誤解していると思います。塩を達成するために何が設計されているかを理解していれば、おそらくこの質問をすることはないでしょう。唯一の目的は、事前に計算されたテーブル(「レインボーテーブル」)が攻撃の効果的な形式になるのを防ぐために、各パスワードに一定のレベルの一意性を提供することです。
その結果、「秘密」にしたり、パスワードにエントロピーを追加したりするようには設計されていません。そのため、パスワードのハッシュと一緒に格納されます。実際、ほとんどの場合、アプリケーション自体がパスワードの正しいハッシュを計算するためにソルトにアクセスする必要があるため、それは不可は秘密です。アプリケーションへのアクセスを許可することは非常に困難ですが、アプリケーションに違反した攻撃者が同じ特権を取得するのを防ぎます。
とにかく実際の質問に答えてください-塩は未知であり、何らかの理由で取得できなかったために塩を「分解」する必要があった理論的な世界では、パスワードと同じレベルの複雑さになります。基本的に(文字スペース)^(長さ)。
あなたの例では、「H0mRpD2XJZDguAzxTehwzu」のハッシュを与えます。大文字/小文字の英数字が62文字の文字スペースであり、長さが22文字であると想定しています。したがって、毎秒10億回の推測を想定すると、62 ^ 22 = 3.397504e + 23年の推測になります。言い換えれば、解読不可能です(これは、パスワードが既知であり、システム全体のソルトを単純に推測しようとしていることを前提としています)。
ソルトはパスワードの隣に保存されます。それがそのようでなければならないというルールはありませんが、それはソルトの意図された目的の論理的な結果です。レインボーテーブルを作成するのは簡単なことではありません。ソルトのポイントは、攻撃者がソルトされたパスワードごとに個別のレインボーテーブルを必要とすることです(この場合、代わりに各パスワードハッシュを直接攻撃する方が簡単です)。
あなたは saltに関する長い回答 を読むことができます。これは、それを秘密にしておく意味がない理由を明確にするはずです。
秘密の塩を入れたい場合は、一般的に呼ばれている a pepper を読んでくださいaddsアプリケーション全体の秘密鍵をソルト付きパスワードに追加します。これはできます部分的な違反(SQLインジェクションなどによるデータベースの侵害など)から保護しますが、完全なシステム違反の場合は、コショウの価値を保護するハードウェアセキュリティモジュール(HSM)。
攻撃者がハッシュだけを知ってソルトを知らない場合、考えられるすべてのパスワードだけでなく、考えられるすべてのソルトを使用してすべての可能なパスワードをテストする必要があります。長くランダムなソルト値では、これは実際には不可能です。
ただし、これは現実的なシナリオではありません。攻撃者がシステムを危険にさらした場合、ハッシュとソルトの両方のデータベースを危険にさらしたと想定する必要があります。これら2つのデータセットは常に一緒に使用されるため、何らかの方法で分離することは不可能です。