web-dev-qa-db-ja.com

独自のソルトハッシュの比較

ハッシュされた識別子の値を比較する必要があるシステムがあります。レインボーテーブルでクラックが発生するのを防ぐために、ハッシュをソルトしたい。

ただし、システムはハッシュされた識別子を比較できる必要があるため、すべてのハッシュに同じソルトを使用する必要があるようです。

共通ソルトは既存のレインボーテーブルからデータを保護するのに役立ちますが、攻撃者は1つのハッシュをブルートフォースクラッキングし、共通ソルトを決定してから、残りのハッシュをクラッキングすることができます。

私の質問は、一致のためにそれらを使用する機能を維持しながら、識別子を保存するより安全な方法はありますか?

1
Chris Parton

どんな「マッチング」をしようとしていますか?

あなたは本当にそれらを比較する必要がありますかお互いに(これは珍しいでしょう)?または、特定のユーザーが特定のパスワードを知っていることを確認する必要があるだけですか(通常の使用例)?

基本認証を実行しようとしているだけの場合は、これが想定を機能させるためのユニークなソルティングの方法です。認証システムは各固有のソルトを知っており、ユーザーがログインしようとすると、そのユーザー固有のソルトを使用して、提示されたパスワードからハッシュを生成します。一致する場合、認証は成功です。

ユーザーのパスワードを相互に比較する必要はありません。実際、多くのユーザーで同じソルトを使用することで、仮にカスタムのRainbowテーブルに耐性がある場合でも、攻撃者が1人のユーザーのパスワードを解読するとすぐに、そのパスワードが解読されますそのパスワードを使用してください。これにより、適切なハッシュのセキュリティ値が低下します。

必要に応じて、サイト全体に追加のソルト(「コショウ」)を追加することもできます。しかし、ペッパーをHSMに保存しているのでない限り、攻撃者がシステムを危険にさらしてハッシュを盗むことができる場合、おそらく認証を実行するコードにアクセスでき、ディスクまたはメモリからそのペッパーをプルすることができます。

ユーザーごとの大きなソルトを使用します-非常に大規模なユーザーベース全体で一意であることを仮想的に保証するのに十分ランダムで十分な大きさです。

2
Royce Williams

レインボーテーブルでクラックが発生するのを防ぐために、ハッシュをソルトしたい。

ただし、システムはハッシュされた識別子を比較できる必要があるため、すべてのハッシュで同じソルトを使用する必要があるようです。

これは基本的に互換性がありません。各パスワードに値を追加することにより、攻撃者がパブリックRainbowテーブル(たとえば、一部のWebサイトから)を使用するのを防ぐことができますが、攻撃者はランダムな値を含む独自のカスタムRainbowテーブルを作成できます。ソルトが「秘密ではなくユニーク」であることの要点は、どんな種類のレインボーテーブルも使用できないようにすることです。

その値を秘密に保つことができれば、ハッシュは安全なままです。しかし、もしそれが漏れたら、塩分がないのと同じくらい悪いです。

暗号化(削除された回答で提案されているように)にはほぼ同じ特性があります。暗号化キーが秘密のままである場合、それは素晴らしいことです。しかし、それがリークした場合は、単純なハッシュに戻ります。実際、暗号化はworseなので、実際にはプレーンハッシュに戻ります。ハッシュに秘密の値が混在している場合でも、インターネットから数ギガバイトをダウンロードする代わりに、少なくとも攻撃者は独自のカスタムRainbowテーブルを作成する必要があります。

ハッシュと混合された秘密の値は通常「ペッパー」値と呼ばれますが、ここではそれを使用するのをためらっています。通常、標準シナリオは、アプリケーションコードとは別のデータベースシステムです。攻撃者がSQLインジェクションの脆弱性を発見し、データベースが適切に構成されている場合、攻撃者はファイルシステム上の任意のファイルを読み取ることができません。ユーザーのパスワードに適用される設定ファイルに秘密の値がある場合、その秘密の値が欠落しているため、攻撃者はハッシュをクラックできません。カスタムシナリオについて説明しているので、これが同じタイプの状況になるかどうかはわかりません。また、コショウは塩に追加され、コショウを優先して塩を除外することは決して推奨されません。しかし、今削除された答えも言ったように、塩なしのコショウは何もないよりはましです。

攻撃者は1つのハッシュをブルートフォースクラッキングし、共通の塩を決定してから、残りのハッシュをクラッキングする可能性があります。

そして、それがあなたが十分に大きな秘密を混ぜなければならない理由です:)。そのためには、128ビット(16バイト)以外であれば十分です。head -c 16 /dev/urandom | base64を使用して生成します。 (Windowsでは、サードパーティのツールなしでシステムのCSPRNGと簡単に対話する方法がわかりません。)

照合に識別子を使用する機能を維持しながら識別子を保存するより安全な方法はありますか?

Royceが提起するように、「マッチング」をどのように定義するかという問題になります。実際、同等にするためにそれらを一致させる必要がある場合、(私の知る限りでは)2つのプロパティの基本的な非互換性に遭遇します。しかし、Royceが言っているように、元のパスワードと一致させる必要がある場合は、通常のsalt + pepperスキームを使用できます。ここで、 saltはエントリごとに一意です 、および pepperは、漏洩したデータベースが脆弱なパスワードで壊滅的になることを防ぐためのグローバルシークレット です。

2
Luc