
暗号学において、鍵導出関数(KDF)は、擬似乱数関数(通常は暗号ハッシュ関数またはブロック暗号を使用)を使用して、マスターキー、パスワード、パスフレーズなどの秘密の値から 1 つ以上の秘密鍵を導出する暗号アルゴリズムです。[ 1 ] [ 2 ] [ 3 ] KDF は、鍵をより長い鍵に拡張したり、必要な形式の鍵を取得したりするために使用できます。たとえば、Diffie–Hellman 鍵交換の結果であるグループ要素をAESで使用する対称鍵に変換するなどです。鍵付き暗号ハッシュ関数は、鍵導出に使用される擬似乱数関数の一般的な例です。[ 4 ]
意図的に処理速度を遅くした(キーストレッチング)最初のパスワードベースの鍵導出関数は「crypt」(またはmanページから「crypt(3)」)と呼ばれ、 1978年にロバート・モリスによって発明されました。これは、修正されたDES暗号化アルゴリズム(リアルタイムコンピュータクロックから読み取った12ビットの数値を使用して計算を摂動させる)を25回繰り返すことにより、定数(ゼロ)を、ユーザーのパスワードの最初の8文字を鍵として使用して暗号化します。結果として得られる64ビットの数値は、印刷可能な11文字としてエンコードされ、Unixパスワードファイルに保存されます。[ 5 ]当時は大きな進歩でしたが、PDP-11時代以降のプロセッサ速度の向上により、 cryptに対する総当たり攻撃が可能になり、ストレージの進歩により12ビットのソルトが不十分になりました。crypt関数の設計では、ユーザーのパスワードが8文字に制限されているため、鍵空間が制限され、強力なパスフレーズが不可能になります。
汎用ハッシュ関数では高いスループットが望ましい特性である一方、総当たり攻撃からの防御が最重要課題となるパスワードセキュリティアプリケーションでは、その逆が当てはまります。GPU 、FPGA、さらにはASICといった大規模並列ハードウェアが総当たり攻撃に利用されるようになったことで、適切なアルゴリズムの選択がますます重要になっています。優れたアルゴリズムは、CPUだけでなく、現代の大規模並列プラットフォームのコストパフォーマンス上の優位性にも抵抗し、一定の計算コストを課す必要があるからです。この目的のために、bcrypt、scrypt、そして最近ではLyra2やArgon2(後者はパスワードハッシュコンペティションの優勝者)など、さまざまなアルゴリズムが設計されています。攻撃者によって約3600万件のパスワードハッシュが盗まれた大規模なAshley Madisonのデータ漏洩事件は、パスワードのセキュリティにおいてアルゴリズムの選択がいかに重要であるかを如実に示しました。ハッシュを保護するためにbcryptが使用されていたものの(大規模な総当たり攻撃による解読はコストと時間がかかる)、侵害されたデータに含まれるアカウントのかなりの部分には、高速で汎用的だが安全性の低いMD5アルゴリズムに基づくパスワードハッシュも含まれており、そのため1100万以上のパスワードが数週間で解読されることが可能になった。[ 6 ]
2017年6月、米国国立標準技術研究所(NIST)は、デジタル認証ガイドラインの改訂版であるNIST SP 800-63B-3 [ 7 ] 5.1.1.2を発行し、次のように規定しました。「検証者は、記憶された秘密情報(パスワードなど)をオフライン攻撃に耐性のある形式で保存しなければならない。記憶された秘密情報は、適切な一方向鍵導出関数を使用してソルト化およびハッシュ化されなければならない。鍵導出関数は、パスワード、ソルト、およびコスト係数を入力として受け取り、パスワードハッシュを生成する。その目的は、パスワードハッシュファイルを入手した攻撃者によるパスワード推測の試行をそれぞれコストのかかるものにし、したがって推測攻撃のコストを高くするか、または不可能にすることである。」
PBKDF2 [ 2 ]などの最新のパスワードベース鍵導出関数は、SHA-2などの認知された暗号学的ハッシュに基づいており、より多くのソルト (少なくとも 64 ビットでランダムに選択) と高い反復回数を使用します。NIST は、最小反復回数を 10,000 回と推奨しています。[ 7 ] : 5.1.1.2 「特に重要な鍵、または非常に強力なシステム、あるいはユーザーが体感するパフォーマンスが重要でないシステムの場合、10,000,000 回の反復回数が適切である可能性があります。」 [ 8 ] : 5.2
KDFの本来の用途は鍵導出、つまり秘密のパスワードやパスフレーズから鍵を生成することです。このテーマのバリエーションには以下のようなものがあります。
鍵導出関数は、通常、暗号鍵として直接使用するのに適した特性を持たない秘密のパスワードやパスフレーズから鍵を導出するアプリケーションでも使用されます。このようなアプリケーションでは、パスワードやパスフレーズの入力値に対する総当たり攻撃や辞書攻撃を阻止するために、鍵導出関数を意図的に遅くすることが一般的に推奨されます。
このような使用法は、 DK = KDF(key, salt, iterations)と表すことができ、ここでDKは導出された鍵、KDFは鍵導出関数、keyは元の鍵またはパスワード、saltは暗号ソルトとして機能する乱数、iterations はサブ関数の反復回数を表します。導出された鍵は、システムの鍵として元の鍵またはパスワードの代わりに使用されます。ソルトの値と反復回数 (固定されていない場合) は、ハッシュ化されたパスワードとともに保存されるか、暗号化されたメッセージとともに平文(暗号化されていない) で送信されます。[ 10 ]
総当たり攻撃の難易度は反復回数が増えるにつれて高くなります。反復回数の実際的な制限は、ユーザーがコンピュータへのログインや復号化されたメッセージの表示に目に見える遅延を許容できないことです。ソルトを使用することで、攻撃者が派生キーの辞書を事前に計算することを防ぐことができます。[ 10 ]
鍵強化と呼ばれる別のアプローチでは、ランダムなソルトで鍵を拡張しますが、(鍵ストレッチとは異なり)ソルトを安全に削除します。[ 11 ]これにより、攻撃者と正当なユーザーの両方がソルト値を総当たりで検索する必要があります。[ 12 ]鍵ストレッチを紹介した論文[ 13 ]では、この以前の手法に言及し、意図的に別の名前を選択しましたが、「鍵強化」という用語は現在、鍵ストレッチを指すためによく(おそらく誤って)使用されています。
鍵導出関数 (KDF) は、元々は鍵導出に使用されていましたが、 passwdファイルやシャドウパスワードファイルで使用されるようなパスワードハッシュ(ハッシュ比較によるパスワード検証) での使用の方がよく知られています。パスワードハッシュ関数は、総当たり攻撃の場合に計算コストが比較的高くなるように設計されており、KDF はこの特性を組み込んで設計されています。[ 14 ]この文脈では、非秘密パラメータは「ソルト」と呼ばれます。
2013年に、パスワードハッシュの新しい標準アルゴリズムを選択するためのパスワードハッシュコンペティションが発表されました。2015年7月20日にコンペティションが終了し、Argon2が最終的な勝者として発表されました。他の4つのアルゴリズム、Catena、 Lyra2、Makwa、yescryptが特別表彰を受けました。[ 15 ]
2023年5月現在、Open Worldwide Application Security Project (OWASP) は、パスワードハッシュに以下のKDFを推奨しており、優先順位順にリストされています。[ 16 ]