1. ホーム
  2. security

[解決済み] ベストプラクティス。パスワードのソルティングとペパリング?

2022-04-23 09:28:14

質問

あるディスカッションで、私がやっていたのは実はパスワードの塩漬けではなく、ペパリングだったということを知り、それ以来、このような関数で両方をやるようになりました。

hash_function($salt.hash_function($pepper.$password)) [multiple iterations]

選択したハッシュアルゴリズム(特定のアルゴリズムではなく、ソルト&ペッパーの議論にしたいのですが、私は安全なものを使っています)は無視して、これは安全なオプションですか、それとも何か違うことをすべきですか?この用語に馴染みのない方のために。

  • A ソルト は、通常、データベース内の文字列と一緒に保存されるランダムに生成される値で、ハッシュテーブルを使用してパスワードを解読することを不可能にするために設計されています。各パスワードはそれぞれソルトを持っているため、パスワードを解読するためには、すべてのパスワードを個別にブルートフォースする必要があります。しかし、ソルトはパスワードのハッシュとともにデータベースに保存されているため、データベースの侵害は両方を失うことを意味します。

  • A ペッパー は、データベースとは別に保存されるサイト全体の静的な値で (通常はアプリケーションのソースコードにハードコードされます)、秘密であることを意図しています。データベースを侵害されても、アプリケーションのパスワードテーブル全体がブルートフォースされないようにするために使用されま す。

また、パスワードにソルティング&ペパリングを施すことは、ユーザーのセキュリティを守るための最良の選択でしょうか?また、この方法にはセキュリティ上の欠陥がある可能性がありますか?

注:議論の目的のために、アプリケーションとデータベースは別々のマシンに保存され、パスワードなどを共有していないと仮定します。したがって、データベースサーバーへの侵入が自動的にアプリケーションサーバーへの侵入を意味するわけではありません。

解決方法は?

わかりました。このことについて書く必要があることを見て オーバー オーバー は、pepperだけで最後のcanonicalの答えを出します。

ピーマンの見かけの良さ

ハッシュ関数の安全性を高めるために、コショウを使うのはごく当たり前のことのように思えます。つまり、攻撃者がデータベースを取得するだけなら、ユーザのパスワードは安全であるべきですよね?論理的でしょう?

だから、多くの人がペッパーズを信じるのです。それは"makes sense"です。

ペッパーの実態

セキュリティや暗号の分野では、「理にかなっている」だけでは十分ではありません。証明可能でなければならないのです。 そして 安全であるとみなされるためには、理にかなっている必要があります。さらに、保守可能な方法で実装可能でなければなりません。最も安全なシステムでも保守できないものは安全でないとみなされます(そのセキュリティの一部が崩れると、システム全体が崩壊してしまうからです)。

そしてピーマンは、証明可能なモデルにも保守可能なモデルにも当てはまらない......。

ペッパーの理論的問題点

さて、お膳立ては整ったので、ピーマンの何がいけないのかを見てみましょう。

  • あるハッシュを別のハッシュに送り込むのは危険です。

    あなたの例では、次のようにします。 hash_function($salt . hash_function($pepper . $password)) .

    私たちは過去の経験から、あるハッシュ結果を別のハッシュ関数に投入するだけで、全体の安全性が低下することを知っています。なぜなら、両方のハッシュ関数が攻撃のターゲットになり得るからです。

    そのため、以下のようなアルゴリズムが採用されています。 PBKDF2 は、特殊な演算で結合する(この場合はhmac)。

    要は、大したことではないが、ただ投げればいいという些細なものでもない、ということだ。暗号システムは、quot;should work"のケースを避け、代わりにquot;designed to work"のケースに焦点を当てるように設計されています。

    これは純粋に理論的に見えるかもしれませんが、実はそうではありません。例えば Bcryptは任意のパスワードを受け入れることができません . そのため bcrypt(hash(pw), salt) よりもはるかに弱いハッシュを生成することができます。 bcrypt(pw, salt) もし hash() はバイナリ文字列を返します。

  • デザインに逆らう仕事

    bcrypt(および他のパスワードハッシュアルゴリズム)は、ソルトを使用して動作するように設計されています。ペッパーという概念は導入されていません。これは些細なことのように思えるかもしれませんが、そうではありません。なぜならば、ソルトは秘密ではないからです。攻撃者に知られる可能性のある値に過ぎない。一方、ペッパーは、その定義からして、暗号上の秘密である。

    現在のパスワードハッシュアルゴリズム(bcrypt、pbkdf2など)は、すべて1つの秘密の値(パスワード)しか取り込まないように設計されています。アルゴリズムに別の秘密を追加することは全く研究されていない。

    だからといって、安全でないとは言えない。安全かどうかわからないということです。セキュリティや暗号に関する一般的な推奨事項は、「わからなければ、安全ではない」ということです。

    ですから、暗号技術者が秘密の値(ペッパー)を使用するためにアルゴリズムを設計し、審査するまでは、現在のアルゴリズムはペッパーと一緒に使用すべきではありません。

  • 複雑さはセキュリティの敵

    信じられないかもしれませんが 複雑さはセキュリティの敵 . 複雑そうに見えるアルゴリズムを作ることは、安全かもしれないし、そうでないかもしれない。しかし、安全でない可能性はかなり高い。

ペッパーの重大な問題点

  • メンテナンスができない

    Pepperの実装では、pepperキーを回転させることができません。pepperは一方向関数の入力で使用されるので、値の寿命が尽きるまでpepperを変更することはできません。つまり、キーの回転をサポートするためには、奇妙なハックを考え出す必要があるということです。

    これは 極めて 暗号の秘密を保管する際には必ず必要なことなので、重要です。鍵をローテーションする仕組みがない(定期的に、そして侵入された後に)ことは、セキュリティ上の大きな脆弱性です。

    そして、現在のペッパーアプローチでは、すべてのユーザーがローテーションによってパスワードを完全に無効化されるか、ローテーションのために次のログインまで待つ必要があります(それはないかもしれません)...。

    つまり、あなたのアプローチは基本的に即座にダメということになります。

  • 独自の暗号を開発する必要がある。

    現在のアルゴリズムはペッパーの概念をサポートしていないので、ペッパーをサポートするためにアルゴリズムを構成するか、新しいものを発明する必要があります。そして、それがなぜ本当に悪いことなのか、すぐに理解できないなら。

    <ブロッククオート

    最も無知なアマチュアから最高の暗号家まで、誰でも自分自身が破れないアルゴリズムを作ることができるのです。

    NEVER 自分で暗号を巻いて...。

より良い方法

つまり、上に詳述した問題のうち、2つの対処法があるということです。

  • 既存のアルゴリズムをそのまま利用する

    bcryptやscryptを正しく(高いコストで)使えば、最も弱い辞書パスワード以外は統計的に安全であるはずです。コスト5でbcryptをハッシュ化した現在の記録は、1秒間に71kハッシュです。この速度では、6文字のランダムなパスワードでさえ、解読するのに何年もかかるでしょう。そして、私が推奨する最小コストが10であることを考えると、1秒あたりのハッシュ数は32分の1に減少します。つまり、1秒間に約2200個のハッシュしかできないことになります。この速度であれば、辞書に載っているフレーズや修正も安全かもしれません。

    さらに、そういった弱いクラスのパスワードは入り口でチェックして、入れないようにすべきです。パスワードのクラッキングが進むにつれて、パスワードの品質要件も高度になるはずです。統計的なゲームであることに変わりはありませんが、適切な保管方法と強力なパスワードがあれば、誰もが実質的に非常に安全であるはずです...。

  • 保存前に出力ハッシュを暗号化する

    セキュリティの領域には、これまで述べてきたようなことをすべて処理できるように設計されたアルゴリズムが存在します。それはブロック暗号です。可逆的なので、鍵を回転させることができます(やった!保守性!)。設計通りに使えるから良い。ユーザーには何も情報を与えないから良い。

    もう一度、この行を見てみましょう。攻撃者があなたのアルゴリズムを知っているとしましょう(これはセキュリティのために必要なことで、そうでなければ無名によるセキュリティです)。従来のペッパー方式では、攻撃者はセンチネルパスワードを作成することができ、ソルトと出力を知っているので、ペッパーをブルートフォースで実行することができます。それは難しいですが、可能性はあります。暗号の場合、攻撃者は何も得られません。ソルトはランダムなので、センチネルパスワードも役に立ちません。ですから、攻撃者に残された最良の方法は、暗号化されたフォームを攻撃することです。つまり、攻撃者はまず暗号化されたハッシュを攻撃して暗号化キーを復元し、次にハッシュを攻撃しなければならないのです。しかし、そこには ロット 暗号の攻撃に関する研究が進んでいるので、それに頼りたいですね。

TL/DR

ペッパーは使わないでください。サーバーサイドのシークレットを使わない(そう、大丈夫)、保存前にブロック暗号を使って出力ハッシュを暗号化する、という2つのより良い方法があるのです。