Wikipediaのページ key derivations functions によると、KDFの目的は暗号化のための秘密鍵を導出することです:
暗号化では、鍵導出関数(KDF)は、疑似ランダム関数を使用して、マスター鍵、パスワード、パスフレーズなどの秘密値から1つ以上の秘密鍵を導出します。[1] [2] KDFを使用して、キーをより長いキーに拡張したり、Diffie-Hellmanキー交換の結果であるグループ要素をAESで使用する対称キーに変換するなど、必要な形式のキーを取得したりできます。キー付き暗号ハッシュ関数は、キーの導出に使用される疑似ランダム関数の一般的な例です。[3]
Curve25519鍵交換を完了し、対称アルゴリズムに鍵を使用したいとします。 AES。
すべてのKDFが遅いわけではありません。 [〜#〜] hkdf [〜#〜] のようなものは非常に高速であり、基礎となるPRFへの呼び出しはほんの一部です。
KDFは、パスワードなどの潜在的に低いエントロピー入力を、暗号化キーやパスワード検証などの高エントロピー出力に変換することを意図している場合にのみ低速になります。このシナリオでは、このような関数は、計算時間を追加するために遅くなるように設計されていますあたかも攻撃者が実際に使用されているものよりも高いエントロピーでシークレットをブルートフォースにしようとしました。
Curve25519鍵交換後の共有秘密鍵のようなものについては、一般的に高速なKDFを好むでしょう。たとえば、 Noise protocol framework はHDKFを使用して、曲線の乗算から派生した共有秘密から暗号化キーを生成します。あなたはcan生の共有シークレットをキーとして直接使用しますが、ほとんどのプロトコルは実際には何らかの形式のKDFを使用して、前方機密などの機能を可能にします。
ここでの混乱は、2つの異なる種類の鍵生成関数があり、人々はしばしば、どちらが意味するのかを明確にせずに(または2つあることさえ理解していない)「鍵導出関数」と言うことがある:
HKDFのようなキーベースの導出関数は、入力が偏るか、部分的に予測可能であると仮定しますが、それ以外の場合は、確実に推測できないほど十分な最小エントロピーを持っています。 Diffie-Hellman交換によって生成された共有秘密は、教科書の例の1つです。
一方、パスワードベースの機能は、入力のエントロピーが低いと想定しているため、推測攻撃に対して妥当な限り高いコストを課すように設計されています(正直な関係者にとっては耐え難いほどのコストになることはありません)。反復回数を増やして計算を遅くするのは古典的な手法ですが、scryptやArgon2などの新しい関数はこれを超えてmemory-hardになることを目指しています。
Curve25519共有キーでKDF、またはそれに関して安全なハッシュを使用する理由は、ビットがランダムに分散されないためです。約126ビットの「セキュリティ」を含む32バイトの「ポイントデータ」があります。
それで...どのビットを選びますか?最初の126ビットを取り、128ビットキーの残りの2ビットをゼロのままにしますか?または、最後の126ビットを取得しますか?または、途中から128ビットを取り出しますか?他のいくつかの戦略?どのようにして正しいビットを選んだと思いますか?悪用可能なパターンがないことをどのようにして知っていますか?
安全なハッシュまたはKDFを使用すると、これらすべての問題が解決されます。 Something-something-inputは、128ビットのかなり完全にランダムな出力(または、ランダムに見える)を提供します。または、必要なビット数。エントロピーを無駄にすることはなく、「良い」ビットを選択したかどうかを心配する必要もありません。また、ECCの計算から得られる悪用される可能性のある明白なパターン(完全に「ランダムな見た目」ではない)になるリスクもありません。もちろん、エントロピーを伸ばしても「魔法のように」追加されることはありませんが、要点は、外部の観測者がそれがどこにあるかを知ることができないということです。 KDFまたはハッシュは低速である必要はありません(そしてほとんどの場合である必要はありません)。
パスワードまたはその他のユーザー入力にslowハッシュまたはKDFを使用する理由は、人間からのものはすべて、恥ずかしいほどにエントロピーが低く、ブルートフォース攻撃を受けやすいためです。辞書(および明白な順列)。最近のコンピューターは文字通り1秒あたり数億の単純なハッシュを実行できるため、パスワードデータベースが盗まれた場合は問題になります。攻撃者はデータベース全体を破壊することはできませんが、故意に遅い関数を使用しない場合、数人のユーザーのパスワードを取得するのはほんの一瞬です。予想される攻撃者にかかる時間が長いほど、より良いです。パスワードを破るのに必要な作業が増えるということは、違反があった場合に反応してユーザーに通知するための時間枠が増えることを意味します。
同じことが、例えば暗号化されたディスクまたはKeepassファイルへのアクセス。攻撃者が1秒間に1〜2億のパスワードを試すことができる場合、暗号化をまったく行わないこともできます。適切なパスワードを選択するためにどれほど注意を払ってもかまいません。
KDFの実行にかかる時間が1秒あたり3〜4個のパスワードを攻撃者が試行できる場合、そのレートで一致を見つけるのに永遠にかかるため、パスワードは基本的に「解読不可能」です。
もちろん、これにより、ボリュームのロックを解除するのがより高価になります。ただし、これは1回のみであり、攻撃者は何度も実行する必要があります。