パスワードハッシュが汎用ハッシュと違う理由
SHA-256 は「速い」ように設計されています。その速さがパスワード用途では危険性そのものです。漏洩 DB に対し攻撃者は GPU 1 枚で毎秒数十億の SHA-256 を試せます。パスワードハッシュ関数は意図的に遅く(通常 100 ms 程度)、メモリも要求します(CPU より高価なリソース)。「不可能にする」ではなく「経済的に不可能にする」ことが目標です。
bcrypt — 長年の定番
bcrypt は 1999 年に Blowfish 暗号をベースに作られました。コストファクター(work factor)が調整可能で、1 増やすごとに計算時間が倍になります。2026 年時点ではコスト 12〜14 が妥当です。ほぼ全言語で対応があり、長年の解析でも実用的な攻撃は見つかっていません。弱点はメモリ使用量が固定で小さく、GPU や FPGA で比較的効率的に攻撃できる点です。
scrypt — メモリハードの先駆者
scrypt は 2009 年に、ハードウェア加速攻撃への耐性を狙って設計されました。1 ハッシュごとに大きなメモリ(通常 16〜64 MB)が必要で、GPU や ASIC ではメモリ実装が高コストなため攻撃難度が大きく上がります。トレードオフは設定が複雑(N、r、p の 3 つのパラメータ)で、メモリ制約のあるサーバでは負担が大きくなる点です。
Argon2 — 現代の本命
Argon2 は 2015 年のパスワードハッシュコンペで優勝し、現在の推奨デフォルトです。3 バリアントあります。Argon2d(データ依存・速いがサイドチャネル脆弱性)、Argon2i(データ非依存・共有メモリ環境で安全)、Argon2id(ハイブリッド・多くの用途で推奨)。Argon2 は最も柔軟(時間・メモリ・並列度を独立に調整可能)かつ最も近代的で、既知攻撃に対して最も強固です。
比較表
- bcrypt: 1999、時間コストのみ、メモリ約 4 KB、対応言語が広い。
- scrypt: 2009、メモリハード、N/r/p の調整が必要、設定難易度高め。
- Argon2id: 2015、時間・メモリ・並列度を調整可能、現行推奨。
チューニングパラメータ
いずれの関数もパラメータでハッシュ時間とセキュリティのバランスを取れます。本番サーバで 1 ハッシュ約 100 ms が目安です。ユーザーログインでは気にならず、総当たり規模ではコストが莫大になります。OWASP は Argon2id でメモリ 19 MiB、反復 2、並列 1 を最低ラインとして推奨。bcrypt は 2026 年時点でコスト 12 以上が下限。scrypt は N=2^17(約 128 MB)、r=8、p=1 が一般的です。
移行戦略
既存ユーザーが bcrypt で保存されていて Argon2id へ移行する場合、ログイン時再ハッシュが標準手法です。ログイン成功時に旧ハッシュで検証してから即座に新関数で再ハッシュし、保存レコードを更新します。数ヶ月で大半のアクティブユーザーが透過的に移行されます。非アクティブユーザーはそのまま bcrypt のままで構いません(依然として安全です)。
ペッパーは必要?
ペッパーは全パスワードに共通で混ぜる単一の秘密値で、DB とは別の場所(HSM や環境変数)に保管します。ソルトの代わりにはなりません(各ユーザーは個別のソルトが必要)が、DB だけ漏洩しシークレットストアが守られているケースで深層防御として機能します。高セキュリティ用途では推奨します。