パスワード保護の「終わりのない戦い」:Argon2とbcryptで防御の要を固める
現場でインシデント対応をしていると、「パスワードはハッシュ化しています」という言葉をよく耳にする。だが、その中身を覗いてみると、いまだにMD5やSHA-1、あるいは「ソルトなしのSHA-256」といった、現代の攻撃者からすれば「どうぞ復号してください」と言わんばかりの代物に出くわすことが少なくない。
今日は、なぜ過去の遺物が危険なのか、そして現代において「鉄壁」とされるArgon2やbcryptをどう実装すべきか、現場の視点で切り込む。
—
1. なぜMD5やSHA-1は「終わった」のか?
MD5やSHA-1がダメな理由は一つ、「計算が速すぎる」からだ。
攻撃者は流出したデータベースを手に入れると、GPUクラスタやクラウドの計算資源をフル活用して「総当たり攻撃(Brute-force)」や「レインボーテーブル攻撃」を仕掛ける。MD5なら、現代の安価なGPUで1秒間に数千億回もの計算が可能だ。つまり、どんなに複雑なパスワードを設定していても、数分から数時間で「元の文字列」が露呈する。
「ハッシュ化しているから大丈夫」は、15年前の常識だ。今の戦場では、「あえて計算を遅くする」ことこそが防御の基本となる。
—
2. 現代の標準:bcryptとArgon2
現代のパスワードハッシュに必要な要素は以下の2つだ。
1. ソルト(Salt): パスワードごとにユニークなランダム値を付与し、同じパスワードでもハッシュ値が異なるようにする。これでレインボーテーブル攻撃を無効化する。
2. ストレッチング(Key Stretching): 計算に意図的に負荷をかけ、総当たり攻撃のコストを跳ね上げる。
現在、実務で選ぶべきは以下の2つだ。
- bcrypt: 長年の実績があり、実装が容易で多くの言語で標準的にサポートされている。まずはこれを選べば間違いない。
- Argon2 (Argon2id推奨): パスワードハッシュコンペティションの勝者。メモリ消費量や並列度を細かく調整できるため、GPUによる攻撃に極めて強い。現時点での「最強」だ。
—
3. 実践:セキュアな実装サンプル
PHPでの実装(bcrypt)
PHPには標準で `password_hash()` という強力な関数がある。自前でアルゴリズムを組むのは絶対に避けろ。
12]);
// 検証時
if (password_verify($password, $hash)) {
// ログイン成功
} else {
// ログイン失敗(エラーメッセージは「パスワードまたはIDが違います」と統一すること!)
}
?>
Pythonでの実装(Argon2)
Pythonなら `argon2-cffi` を使うのが業界標準だ。
インストール: pip install argon2-cffi
from argon2 import PasswordHasher
ph = PasswordHasher()
ハッシュ化
hash_value = ph.hash(“User_Secret_Password_123”)
検証
try:
ph.verify(hash_value, “User_Secret_Password_123”)
print(“ログイン成功”)
except:
print(“ログイン失敗”)
—
4. 現場で守るべき「3つの鉄則」
コードを書くだけがセキュリティではない。運用面での盲点も押さえておけ。
1. パラメータの調整(Work Factor):
サーバーのCPU性能に応じて、計算コスト(bcryptならcost値、Argon2ならtime_cost等)を調整しろ。「ユーザーがログインボタンを押してから0.5秒〜1秒程度待たされる」くらいが、攻撃者にとっての悪夢であり、ユーザーにとっては許容範囲の遅延だ。
2. エラーメッセージの抽象化:
ログイン失敗時に「パスワードが違います」と返すな。ユーザー名が存在するか否かを攻撃者に教えているのと同じだ。「IDまたはパスワードが正しくありません」と常に同じメッセージを返すこと。
3. データベース自体の防御:
ハッシュ化していても、DBが丸ごと漏洩すれば解析の対象になる。DBへのアクセス制限、通信の暗号化(TLS)、そして万が一の漏洩に備えた「ソルトの取り扱い」を軽視するな。
—
最後に:セキュリティは「コスト」ではなく「信頼のコスト」
「セキュリティ対策は面倒だ」とボヤくエンジニアがいるが、一度でも大規模な情報漏洩を起こせば、その信頼回復にかかるコストは対策費用の数万倍になる。
今回紹介した実装は、明日からの開発にすぐ組み込めるはずだ。もし、今のプロダクトでMD5やSHA-1を使っているなら、今すぐにマイグレーション計画を立てろ。それが、プロのエンジニアとしての最低限の矜持だ。
分からないことがあれば、いつでも相談してくれ。手を動かすエンジニアを、私は全力でサポートする。

コメント