こんにちは!インフラやセキュリティの現場にいると、「パスワードってどうやって安全に保存すればいいの?」とか、「新しいハッシュ関数って何がすごいの?」といった質問をよく受けますよね。
セキュリティの世界は専門用語が多くて、最初は少し身構えてしまうかもしれませんが、一歩ずつ紐解いていけば大丈夫です!今回は、次世代の暗号技術として活躍する「SHA-3(Keccak)」を取り上げ、従来のSHA-2と何が違うのか、そしてなぜ安全なのかを、身近な防犯の例えを交えながら優しく解説していきます。
実務でそのまま使えるコード例も用意したので、一緒に学んでいきましょう!
—
1. パスワードを守る「ハッシュ関数」と「長さ拡張攻撃」の恐怖
まずは、私たちが普段何気なく使っている「ハッシュ関数」のおさらいから始めましょう。
ハッシュ関数とは、どんな長さのデータ(例えばパスワードの「P@ssw0rd123」など)を入力しても、決まった長さの文字列(ハッシュ値)に変換してくれるマジックボックスのようなものです。一度ハッシュ値に変換してしまうと、元のパスワードに戻すことは理論上できません(不可逆性)。これを利用して、データベースにはパスワードの「生データ」ではなく「ハッシュ値」だけを保存しています。
SHA-2が抱えていた「継ぎ足し」の弱点
これまで主役だったSHA-2(SHA-256など)は非常に優秀ですが、構造上のクセがありました。それは「マークシートの答案用紙に、あとからこっそり文字を継ぎ足せる」という性質です。
これをセキュリティの世界では「長さ拡張攻撃(Length Extension Attack)」と呼びます。
家に例えるなら、こんな状態です。
1. あなたが「玄関の鍵と、リビングの鍵を渡します」というメモ(データ)を書き、改ざんされないように末尾に暗号のスタンプ(ハッシュ値)を押して家族に渡しました。
2. 悪い泥棒がそのメモとスタンプをこっそり拾いました。
3. 泥棒は、メモの末尾に「それと、裏口の鍵も渡します」という文章をこっそり継ぎ足し、SHA-2の数学的な性質を利用して、あたかも最初からセットで書かれていたかのような新しいスタンプを偽造してしまいました。
SHA-2は、データを「左から右へ一方向へ流す(マークシートを上から下へ塗りつぶしていく)」ような構造をしていたため、末尾にデータを付け足されると、そこから計算を再開できてしまったのです。
—
2. SHA-3(Keccak)の「スポンジ構造」とは?
このSHA-2の弱点をスパッと解決したのが、次世代の標準であるSHA-3(内部構造のアルゴリズム名は「Keccak:ケチャック」と読みます)です。
SHA-3が採用しているのは、データ処理の仕組みを根本から変えた「スポンジ構造(Sponge Construction)」と呼ばれるアプローチです。これが本当にユニークで、かつ強力なんです。
スポンジの例えで理解するデータ処理
台所にある「食器洗い用のスポンジ」を想像してみてください。
1. 吸収フェーズ(Absorbing):
スポンジに水を吸わせるように、入力データをぐんぐんと取り込んでいきます。SHA-3は、データを一方通行で流すのではなく、スポンジ全体に染み込ませるように混ぜ合わせます。一度スポンジの奥深くまで染み込んだ水は、後から「やっぱり少しだけ追加して、全体のバランスを変えよう」と思っても、綺麗にコントロールできません。これが、SHA-2の弱点だった長さ拡張攻撃を完全にシャットアウトできる理由です。
2. 絞り出しフェーズ(Squeezing):
十分に混ぜ合わせたスポンジを「ギュッ」と絞ることで、必要な長さのハッシュ値(キレイな水)を取り出します。驚くことに、スポンジからは必要であればいくらでも(無限に)データを絞り出すことができます。
この「混ぜ合わせてから絞り出す」というプロセスのおかげで、SHA-3は従来のSHA-2よりも数学的に異なるアプローチでデータを保護し、圧倒的な耐性を誇るようになりました。
—
3. SHA-2 vs SHA-3 の違いまとめ
ここで、実務で知っておくべきSHA-2とSHA-3の違いを整理しておきましょう。
| 比較項目 | SHA-2 (SHA-256など) | SHA-3 (SHA-3-256など) |
| :— | :— | :— |
| 内部構造 | マークシート型(Merkle–Damgård構造) | スポンジ型(Sponge Construction) |
| 長さ拡張攻撃への耐性 | なし(脆弱性への対策が必要) | あり(構造上、完全に防止) |
| 安全性 | 現在も広く使われており十分安全 | さらに堅牢で、SHA-2への攻撃手法とは異なるアプローチで設計 |
| 実務での位置づけ | 標準的・枯れた技術として信頼性が高い | 次世代のスタンダードとして導入が進む |
「じゃあ、今日から全部SHA-3に変えなきゃ!」と慌てる必要はありません。SHA-2も現在直ちに破られるような危険なものではありませんが、新しくシステムを設計する際や、より高い安全性が求められる要件では、SHA-3の採用を強くおすすめします。
—
4. 【実践】PHPでの安全なパスワードハッシュ実装例
「理論は分かったけれど、実際のコードではどう書けばいいの?」という新人エンジニアの方向けに、PHPを使った安全なパスワード保存のサンプルコードを用意しました。
現代のWeb開発において、パスワード保存にはSHA-2やSHA-3を「そのまま」使うのではなく、password_hash() 関数を使うのが鉄則です(これを使うことで、自動的に強力なストレッチングとソルトの付与が行われます)。今回はPHPの標準機能の裏側をイメージしつつ、安全な実装を見ていきましょう。
<?php
/**
* セキュリティエンジニアが推奨する、安全なパスワードハッシュ化のサンプル
*
* 注意: パスワードのハッシュ化には、SHA-2やSHA-3を直接生で使うのではなく、
* 業界標準である bcrypt や Argon2 を内部で利用する password_hash() を使用します。
*/
// 1. ユーザーが入力したパスワード(実際にはフォームから受け取る値)
$rawPassword = 'UserSecurePassword123!';
/**
* 2. パスワードのハッシュ化
* password_hash() は、自動的に「ソルト(ランダムなノイズ)」を生成・付加し、
* さらに計算をあえて遅くする「ストレッチング(コスト調整)」を行ってくれます。
* これにより、万が一データベースが盗まれても、辞書攻撃やブルートフォースからパスワードを守ります。
*/
$hashedPassword = password_hash($rawPassword, PASSWORD_DEFAULT);
// データベースには、必ずこの $hashedPassword を保存します(生パスワードは絶対に保存しない!)
echo "データベース保存用ハッシュ: " . htmlspecialchars($hashedPassword, ENT_QUOTES, 'UTF-8') . "\n";
/**
* 3. ログイン時のパスワード検証
* ユーザーが入力したパスワードが、保存されているハッシュと一致するかを安全に検証します。
*/
$loginInput = 'UserSecurePassword123!';
if (password_verify($loginInput, $hashedPassword)) {
echo "認証成功:パスワードが一致しました!\n";
} else {
echo "認証失敗:パスワードが間違っています。\n";
}
?>
コードのポイント解説
- ソルト(Salt): パスワードにランダムな文字列を混ぜることで、同じパスワードを使っている別ユーザーと異なるハッシュ値を作ります。「合鍵ごとに少しだけ形を変える」ようなイメージです。
- ストレッチング(Stretching): あえてハッシュ計算を何万回も繰り返すことで、攻撃者がパスワードを総当たりで破るスピードを極端に遅くします。「頑丈な二重ロックをかける」のと同じ効果があります。
—
まとめ
今回は、SHA-3のスポンジ構造とSHA-2との違い、そしてパスワード保護の基本について解説しました。
- SHA-2は実績のある優れたアルゴリズムですが、末尾にデータを継ぎ足される「長さ拡張攻撃」の弱点を持っていました。
- SHA-3は「スポンジ構造」を採用することで、データを完全に混ぜ合わせてから絞り出すため、長さ拡張攻撃をシャットアウトできます。
- パスワードの実務的な保存には、ハッシュ関数の基礎を活かしつつ、ソルトやストレッチングを自動で処理してくれる言語の標準関数(PHPの
password_hash()など)を正しく使いましょう。
セキュリティの仕組みは、身近な防犯に置き換えてみるとスッと頭に入ってきますよね。一歩ずつ、確実に安全なシステムを作れるエンジニアを目指していきましょう!質問や感想があれば、ぜひコメント欄で教えてくださいね。
コメント