KDF(鍵導出関数)とは
KDF(Key Derivation Function / 鍵導出関数)は、パスワードや共有秘密、マスターキーなどの入力値から、暗号化に使用する安全な鍵を生成するためのアルゴリズムです。
KDFが必要とされる主な理由は以下の通りです:
- エントロピーの増大:弱いパスワードから強力な鍵を生成
- 鍵の長さ調整:任意の長さの鍵を生成
- ブルートフォース攻撃への耐性:計算コストを意図的に高める
- 複数鍵の生成:一つのマスターキーから複数の用途別鍵を導出
KDFの種類と特徴
パスワードベースKDF(PBKDF)
パスワードから鍵を導出するために設計されたKDFです。ブルートフォース攻撃への耐性を高めるため、意図的に計算を遅くします。
| アルゴリズム | 特徴 | 推奨用途 |
|---|---|---|
PBKDF2 |
広く実装されている。イテレーション数で調整 | レガシーシステム、互換性重視 |
scrypt |
メモリハード。GPU攻撃に強い | 暗号通貨、ディスク暗号化 |
Argon2 |
最新の標準。メモリ・CPU両方調整可能 | 新規開発、パスワードハッシュ |
bcrypt |
パスワードハッシュに特化 | ユーザーパスワード保存 |
非パスワードベースKDF
すでに十分なエントロピーを持つ秘密情報から鍵を導出する場合に使用します:
- HKDF(HMAC-based KDF):Diffie-Hellman鍵交換後の鍵導出に最適
- KDF1/KDF2:古典的なKDF。現在はHKDFを推奨
AIエンジニアとしての実体験
機械学習モデルを配布する際、モデルファイルを暗号化することがあります。このとき、ユーザーが入力するライセンスキーから実際の暗号化鍵を導出するためにKDFを使用します。
from cryptography.hazmat.primitives.kdf.hkdf import HKDF
from cryptography.hazmat.primitives import hashes
import os
# ライセンスキーからAES鍵を導出
def derive_key_from_license(license_key: str, salt: bytes = None) -> bytes:
if salt is None:
salt = os.urandom(16)
hkdf = HKDF(
algorithm=hashes.SHA256(),
length=32, # AES-256用
salt=salt,
info=b"model-encryption-key"
)
return hkdf.derive(license_key.encode()), salt
# パスワードベースの場合(scrypt使用)
from cryptography.hazmat.primitives.kdf.scrypt import Scrypt
def derive_key_with_scrypt(password: str, salt: bytes) -> bytes:
kdf = Scrypt(
salt=salt,
length=32,
n=2**14, # CPUコスト
r=8, # ブロックサイズ
p=1 # 並列度
)
return kdf.derive(password.encode())
自社サーバー運用への応用
ディスク暗号化
LUKS(Linux Unified Key Setup)は、PBKDF2またはArgon2を使用してパスフレーズから暗号化鍵を導出します。
# LUKSボリュームの作成(Argon2使用)
cryptsetup luksFormat --pbkdf argon2id /dev/sdb1
# 既存LUKSのKDFパラメータ確認
cryptsetup luksDump /dev/sdb1 | grep -A5 "PBKDF"
TLSセッション鍵の導出
TLS 1.3では、HKDFを使用してハンドシェイク時に複数のセッション鍵を導出します。
KDFのメリット・デメリット
メリット
- 短く推測されやすいパスワードからでも、ソルトと計算コストにより実質的な安全性を高めた鍵を生成できる
- 1つのマスターシークレットから、用途別(暗号化鍵・認証鍵・IV等)に独立した複数の鍵を安全に導出できる(HKDF)
- パスワードベースKDFはブルートフォース攻撃のコストを意図的に引き上げ、漏洩時の被害を軽減する
- 標準化されたアルゴリズム(PBKDF2、HKDF等)はRFCで仕様が公開されており、実装の相互運用性が高い
デメリット
- パスワードベースKDFの計算コストはサーバーのCPU/メモリ資源を消費するため、大量の同時ログイン処理ではパフォーマンス設計が必要
- パラメータ(イテレーション数、メモリコスト等)の選定を誤ると、安全性が不十分になったり処理が遅すぎたりする
- KDFの種類ごとに用途が異なり(パスワード用途とマスター鍵派生用途を混同しやすい)、誤った組み合わせを選ぶと脆弱性につながる
- 古いアルゴリズム(PBKDF2など)はGPU/ASICによる並列攻撃への耐性がメモリハード系(Argon2、scrypt)より低い
類似技術との違い:パスワードベースKDF vs HKDF
KDFは大きく「低エントロピーの入力を強化するタイプ」と「高エントロピーの秘密から複数鍵を派生するタイプ」に分かれます。目的を混同すると脆弱性につながるため、明確に区別することが重要です。
| 項目 | パスワードベースKDF(PBKDF2/Argon2等) | HKDF |
|---|---|---|
| 入力の性質 | 低エントロピー(人間が記憶するパスワード) | 高エントロピー(鍵交換で得た共有秘密等) |
| 設計目的 | 計算コストを意図的に高め、総当たり攻撃を困難にする | 高速に、かつ暗号学的に安全な形で複数の鍵を派生する |
| 処理速度 | 意図的に低速(ミリ秒〜秒単位) | 高速(マイクロ秒単位) |
| 代表的な用途 | パスワード保存、パスフレーズからのディスク暗号化鍵生成 | TLS 1.3のセッション鍵導出、Signalプロトコル |
誤ってHKDFをパスワードのハッシュ化に使うと、計算コストが低いためブルートフォース攻撃に弱くなります。逆にDiffie-Hellman鍵交換後の共有秘密にArgon2のような低速KDFを使うのは不要な処理コストであり、用途に応じた正しい選択が重要です。
実務での活用シーン・導入時の注意点
主な活用シーン
- ユーザーパスワードの保存(Webアプリケーションの認証システム)
- ディスク・ファイル暗号化のパスフレーズから暗号鍵への変換(LUKS、VeraCrypt等)
- TLS/SSHなどの鍵交換プロトコルにおけるセッション鍵の派生
- ソフトウェアライセンスキーやマスターシークレットから機能別の暗号鍵を生成する設計
導入時の注意点
- 用途に応じたアルゴリズム選定:パスワード保存にはArgon2id、鍵交換後の鍵派生にはHKDFというように目的に合ったKDFを選ぶ
- パラメータの定期見直し:イテレーション数・メモリコストはハードウェア性能の向上に合わせて数年おきに引き上げる
- ソルトの一意性確保:導出のたびに十分な長さ(16バイト以上)のランダムソルトを生成し、再利用しない
- ライブラリの利用:KDFの実装を自作せず、言語標準または実績のある暗号ライブラリ(OpenSSL、cryptography等)を使用する
関連ブログ記事
📝 関連記事
【2026年最新】OpenSSLの深刻な問題とは? - KDFの実装についても触れています。
最新動向(2026年)
Argon2の普及
2015年のPassword Hashing Competitionで優勝したArgon2が、徐々に標準として採用されています。OWASP(Open Web Application Security Project)もArgon2idを第一推奨としています。
ポスト量子暗号への対応
量子コンピュータに対しても、適切なパラメータを選択したKDFは安全であると考えられています。ただし、出力鍵長を2倍にすることが推奨されています。
トラブル事例と対策
⚠️ イテレーション数の不足
問題:PBKDF2のイテレーション数が少なすぎるとブルートフォース攻撃に脆弱
対策:OWASP推奨では最低でも310,000イテレーション(SHA-256使用時)
⚠️ ソルトの再利用
問題:同じソルトを使うとレインボーテーブル攻撃が可能に
対策:各導出ごとに一意のランダムソルト(最低16バイト)を使用
権威あるリソース
- OWASP Password Storage Cheat Sheet
- RFC 5869 - HKDF
- RFC 8018 - PKCS #5 (PBKDF2)
- Argon2 Reference Implementation
関連用語
よくある質問(FAQ)
Q. 鍵導出関数(KDF)とは何ですか?
KDF(Key Derivation Function)はパスワード・マスター鍵等から暗号鍵を生成する関数です。PBKDF2・bcrypt・scrypt・Argon2がパスワードベースKDF(PBKDF)として有名です。HKDF(HMAC-based KDF)はマスターシークレットから複数の鍵を安全に派生するためのRFC 5869標準関数で、TLS 1.3やSignalプロトコルで使われています。
Q. HKDFとPBKDF2の違いは何ですか?
PBKDF2はパスワード(低エントロピー)から鍵を生成するために計算コストを意図的に高くします。HKDFはすでに高エントロピーなシークレット(マスター鍵)から複数の鍵を効率的に派生するために使います(意図的に高速)。用途が異なるため混同しないようにしましょう:パスワードにはArgon2id/PBKDF2、鍵派生にはHKDF/KDFを使います。
Q. TLS 1.3でKDFはどう使われますか?
TLS 1.3ではHKDF(HMAC-Based Key Derivation Function)を使って、ハンドシェイクシークレットからアプリケーションキー・IVなど複数の鍵素材を派生します。HKDF-Extractで共有秘密をプレキーに変換し、HKDF-Expandでトラフィック鍵などを生成します。この設計により、1つの鍵素材から複数の独立した鍵を安全に生成できます。
