鍵導出関数:PBKDF2、Argon2、scryptの比較
パスワードベース暗号化のための鍵導出関数を比較。PBKDF2・Argon2・scryptの強みとトレードオフ。
2026年のパスワード派生暗号化では、 Argon2id が最優先の選択肢です(PHC優勝、OWASPの推奨、GPU・ASIC攻撃への強力な耐性)。 scrypt は信頼性の高い次点(メモリハード、暗号通貨で広く採用)。 PBKDF2-SHA-256 は60万回以上のイテレーションで互換性のある選択として許容されますが、GPU耐性は限定的です。ファイル転送アプリでユーザーがパスワードを入力して共有ファイルを保護する場合、 Argon2id(t=3、メモリ64MiB、並列度4)が現代的な基準です。 PBKDF2 が生き残っているのは Web Crypto API に組み込まれており WASM 依存が不要なためです。
3つの関数を一目で比較
| 項目 | PBKDF2 | scrypt | Argon2id | |---|---|---|---| | 導入年 | 2000年(RFC 2898) | 2009年(RFC 7914) | 2015年(PHC優勝) | | メモリハード | いいえ | はい | はい | | パラメータの柔軟性 | イテレーション数のみ | N、r、p | time、memory、parallelism | | GPU耐性 | 弱い | 中程度 | 強い | | ASIC耐性 | 非常に弱い | 中程度 | 強い | | ブラウザネイティブ(Web Crypto) | はい | いいえ | いいえ | | OWASP 2024推奨 | 許容される代替 | 許容 | 優先 | | ブラウザでの処理時間(現代ハードウェア) | 60万回≒500ms | N=2^17≒800ms | t=3、64MiB≒1秒 |
メモリハードが重要な理由
パスワードベース暗号化の脅威モデルはオフラインのブルートフォース攻撃です。攻撃者は暗号文とソルトを入手し、パスワード辞書を使って鍵を導出しようとします。防御の要は1回の試行コストを高くすることです。
PBKDF2 は CPU 時間のみで試行コストを引き上げます。現代の GPU は毎秒数十億回の SHA-256 演算を実行できるため、ゲーミング GPU は PBKDF2-SHA-256-600000 を1日あたり1,000万〜1億回試行できます。ASIC攻撃者はさらに桁違いの優位性を持ちます。
メモリハード関数( scrypt 、 Argon2 )は試行ごとに固定量のメモリを必要とします。GPU・ASIC はメモリ帯域幅が限られているため、デバイスあたりの並列数が制約されます。64MiB のメモリ要件があれば、16GB VRAM の GPU で同時実行できるのは最大256試行のみです。ブルートフォースの経済的コストは2〜3桁上昇します。
PBKDF2:レガシーな標準
PBKDF2(RFC 2898)は疑似乱数関数(通常 HMAC-SHA-256 または HMAC-SHA-512)をパスワードとソルトに対して繰り返し適用します。調整できるパラメータはイテレーション数のみです。
const passwordKey = await crypto.subtle.importKey(
"raw", new TextEncoder().encode(password),
"PBKDF2", false, ["deriveKey"]
);
const aesKey = await crypto.subtle.deriveKey(
{
name: "PBKDF2",
salt, // ランダム16バイト
iterations: 600000,
hash: "SHA-256",
},
passwordKey,
{ name: "AES-GCM", length: 256 },
false,
["encrypt", "decrypt"]
);
OWASP 2023 は PBKDF2-SHA-256 で最低60万回のイテレーションを推奨しています。利点は Web Crypto に組み込まれているため WASM 不要、FIPS 検証済み、 Node.js とブラウザで同一動作する点です。欠点はメモリハードでないため GPU・ASIC 加速に脆弱であることです。
scrypt:最初のメモリハード実装
scrypt(RFC 7914)は Colin Percival が2009年に Tarsnap 用に開発しました。パスワード素材を大きなメモリバッファを通してミックスし、攻撃者が各試行中にそのバッファを保持することを強制します。
3つのパラメータがあります。
- N:コスト係数(通常2^14〜2^20)。メモリ使用量はおよそ128×N×rバイト。
- r:ブロックサイズ(通常8)。メモリ量と GHASH のイテレーション数に影響。
- p:並列度(通常1)。値を上げると正規の計算も高速化されますが攻撃者も同様なので通常1のままにします。
OWASP は N=2^17、r=8、p=1 を基準として推奨しており、約128MiB を消費し、現代ハードウェアで800ms程度です。 Litecoin や Dogecoin が proof-of-work に scrypt を採用したことで ASIC 開発が進み、元々の非対称的優位性がやや低下しています。
Argon2id:2026年のデフォルト
Argon2 は2015年に Password Hashing Competition で優勝しました。3つのバリアント(Argon2d、Argon2i、Argon2id)のうち、ほとんどの用途には Argon2id が推奨されます。RFC 9106 で2021年に標準化されました。
3つのパラメータがあります。
- t(time):メモリ全体のイテレーション数。通常2〜3。
- m(memory):KiB単位のメモリ量。通常65536(64MiB)以上。
- p(parallelism):並列度。通常1〜4。
OWASP 2024 の最低基準はt=2、m=19456(19MiB)、p=1で、より強固な保護にはt=3、m=65536(64MiB)、p=4を推奨しています。
import { argon2id } from '@noble/hashes/argon2';
import { utf8ToBytes } from '@noble/hashes/utils';
const derivedKey = argon2id(utf8ToBytes(password), salt, {
t: 3, m: 65536, p: 4, dkLen: 32
});
または argon2-browser(WASM)経由で使用できます。
import argon2 from 'argon2-browser';
const hash = await argon2.hash({
pass: password, salt,
type: argon2.ArgonType.Argon2id,
time: 3, mem: 65536, parallelism: 4, hashLen: 32
});
Argon2id は scrypt よりも GPU 攻撃者に対して効果的です。メモリアクセスパターンが大量メモリ設計に適しておらず、ASIC も研究段階にとどまっています。
アプリに合ったパラメータの選定
キャリブレーション方法:ユーザーが許容できる最長待機時間(通常500ms〜2秒)を決め、最も遅いターゲットデバイスで計測し、その予算に合うパラメータを設定します。
HexaTransfer スタイルのパスワード保護ファイル共有では、鍵導出はアップロード時に1回、ダウンロード時に1回だけ行われるため、1〜2秒は許容範囲です。
- PBKDF2-SHA-256:60万〜120万イテレーション
- scrypt:N=2^17、r=8、p=1
- Argon2id:t=3、m=65536、p=4
ソルト管理の基本
3つの KDF すべてでソルトが必要です。ルールは以下の通りです。
- 最低16バイトのランダム値
crypto.getRandomValues()で生成(Math.random()は絶対に使用しない)- パスワードごとにユニーク
- 秘密にする必要はなし — 暗号文と一緒に保存する
ペッパー(全導出に追加する秘密情報)が議論されることもあります。サーバーがダムなストレージになるファイル転送では、サーバー側の秘密情報が存在しないためペッパーに価値はありません。アカウントベースのシステムでは、パスワードデータベースとは別に保存されるサーバー側のペッパーが有効です。
KDF 間の移行
既存の PBKDF2 デプロイから Argon2id に移行する場合は、暗号文のメタデータに KDF識別子("kdf": "pbkdf2-sha256-600000" または "kdf": "argon2id-3-65536-4")を保存します。新しいアップロードには Argon2id を使用し、復号時には識別子に応じた関数を使用します。古い暗号文をブラインドアップグレードしないでください — 再導出にはパスワードが必要です。 LastPass 、 1Password 、 Bitwarden のいずれもこの移行を経験済みです。
bcrypt について
bcrypt(1999年)は適度なメモリハードを持つパスワードハッシュ関数ですが、72バイトの入力制限(長いパスワードがサイレントに切り捨てられる)という欠点があります。2026年の新規開発では Argon2id を優先し、既存システムの維持には bcrypt で問題ありません。
hexatransfer.comでお試しください — 無料、登録不要、最大10GB。
エンドツーエンド暗号化で大容量ファイルを安全に送信
エンドツーエンド暗号化で最大10GBのファイルを無料で転送。アカウント不要。ファイルはアップロード前にブラウザで暗号化されるため、他の誰にも読まれません。
ファイルを送信