はじめに
「ハッシュ化しているから安全です」
――セキュリティ界隈で一番よく聞くけど、一番危険なセリフかもしれません。
ハッシュは暗号技術の中核ですが、用途を間違えると一気に脆弱性に転落します。
この記事では以下を一気に整理します。
- ハッシュの正しい役割
- なぜ SHA-256 はパスワード保存に向かないのか
- ソルト・HMAC の落とし穴
- HMAC-SHA1 の弱鍵を Hashcat で破る実践チャレンジ
1. ハッシュとは何か
ハッシュ関数は、入力データを 固定長の値 に変換する 一方向関数 です。
変換は一方向であるため、ハッシュを逆にして元の入力を復元することは不可能です。
2. 主な用途
| 用途 | 説明 |
|---|---|
| パスワード保存 | 平文を保存せず、ハッシュのみを保存 |
| データ完全性 | ファイル改ざん検知 |
| メッセージ認証 | HMAC による改ざん防止 |
重要なのは、
「同じハッシュでも、用途によって安全性の要求がまったく違う」 という点です。
3.よくあるハッシュの脆弱性
3.1 弱いハッシュアルゴリズム
- MD5
- SHA-1
これらは衝突攻撃が実用レベルで成立します。
「同じハッシュ値を持つ別データ」が作れる時点で、信頼性は崩壊です。
3.2 ソルトなしハッシュ
同じパスワード → 同じハッシュ
= レインボーテーブルの餌食
password123 → e99a18c428cb38d5f260853678922e03
攻撃者「もう答え載ってるじゃん」
3.3. 不適切な HMAC 運用
HMAC は 鍵が命 です。
脆弱になるケース:
- 短い鍵
- 推測可能な鍵
- 使い回し鍵
- 辞書に載ってる鍵(←今回のチャレンジ)
4.なぜ SHA-256 はパスワード保存に向かないのか
SHA-256 は優秀すぎるのが問題です。
- 高速
- GPU に最適化
- 並列計算しやすい
GPU による試行回数の違い(概算)
| アルゴリズム | 試行速度 |
|---|---|
| MD5 | ~1000億 H/s |
| SHA-256 | ~10億 H/s |
| bcrypt (cost=12) | ~1,000 H/s |
| Argon2id | ~100 H/s |
つまり:
SHA-256 → 攻撃者が笑顔
Argon2 → 攻撃者が転職を考える
5.正しいハッシュ関数の選び方
| 目的 | 推奨 |
|---|---|
| パスワード保存 | Argon2 / bcrypt / PBKDF2 |
| データ完全性 | SHA-256 / SHA-3 / BLAKE2 |
| メッセージ認証 | HMAC-SHA256 / HMAC-SHA3 |
SHA-256 は「万能」ではありません。
適材適所が暗号の基本です。
6.チャレンジ:HMAC-SHA1 の秘密鍵を破れ
6.1 問題設定
- Message
CanYouGuessMySecret
- HMAC-SHA1
1484c3a5d65a55d70984b4d10b1884bda8876c1d
鍵が弱い=辞書攻撃が可能。
6.2 Hashcat による実践攻撃
① ハッシュファイル作成
echo -n "1484c3a5d65a55d70984b4d10b1884bda8876c1d:CanYouGuessMySecret" > digest.txt
② Hashcat 実行
hashcat -a 0 -m 150 digest.txt /usr/share/wordlists/rockyou.txt
-
-m 150= HMAC-SHA1 -
-a 0= 辞書攻撃
③ クラック結果
1484c3a5d65a55d70984b4d10b1884bda8876c1d:CanYouGuessMySecret:sunshine
Session..........: hashcat
Status...........: Cracked
Hash.Name........: HMAC-SHA1 (key = $pass)
Hash.Target......: 1484c3a5d65a55d70984b4d10b1884bda8876c1d:CanYouGues...Secret
Time.Started.....: Wed Dec 31 09:09:22 2025 (0 secs)
Time.Estimated...: Wed Dec 31 09:09:22 2025 (0 secs)
Guess.Base.......: File (/usr/share/wordlists/rockyou.txt)
Guess.Queue......: 1/1 (100.00%)
Speed.#1.........: 462.1 kH/s (1.90ms) @ Accel:1024 Loops:1 Thr:1 Vec:8
Recovered........: 1/1 (100.00%) Digests
Progress.........: 2048/14344384 (0.01%)
Rejected.........: 0/2048 (0.00%)
Restore.Point....: 0/14344384 (0.00%)
Restore.Sub.#1...: Salt:0 Amplifier:0-1 Iteration:0-1
Candidates.#1....: 123456 -> lovers1
秘密鍵は RockYou に載っていた
7.何が悪かったのか(設計視点)
| 問題 | 解説 |
|---|---|
| 弱い鍵 | 人間が覚えられる鍵は危険 |
| SHA-1 使用 | 非推奨アルゴリズム |
| 辞書耐性なし | KDF 不使用 |
8. 防御側の正解ムーブ
- HMAC 鍵は ランダム 256bit 以上
- SHA-1 は使用しない
- パスワードは Argon2id
- 鍵管理は KMS or HSM
まとめ(覚えてほしい一文)
ハッシュは「暗号」ではない
設計ミスを隠してくれる魔法でもない
SHA-256 は悪くありません。
使いどころを間違える人間が悪いのです。