# ハッシュ値とは? **一方向性** 元のデータからハッシュ値を簡単に計算できますが、 ハッシュ値から元のデータを再構築するのは非常に難しい(ほぼ不可能)です。 **固定長出力** どんなサイズの入力データでも、ハッシュ関数は固定長の出力を生成します。 たとえば、SHA-1は160ビットのハッシュ値を生成します。 **衝突耐性** 異なる入力データが同じハッシュ値になる(衝突する)確率をできるだけ低くするように設計されています。 ## ハッシュ値の基礎知識 * ソルト: ハッシュ化する前にパスワードに付け足す「ランダムな値」 * SHA-1でもSHA-256でも存在する * レインボーテーブル: 事前に計算されたハッシュ値と対応するプレーンテキストのテーブルです。 * 「よく使われるパスワード」と「そのハッシュ値」をあらかじめ大量に計算して保存した表 * SHA-1でもSHA-256でも存在する ## セキュリティについて ### SHA-1は非推奨 SHA-1は現在脆弱性が指摘されているため、推奨されていません。 SHA-256や他のより安全なハッシュ関数を使うことが推奨されています。 **ハッシュ値の確認** * SHA-1 Centerというサイトにより確認できる * https://sha1.gromweb.com/?hash=e4c6bced9edff99746401bd077afa92860f83de3 ### パスワード処理では 現在ではSHA256+ソルトでも、パスワード保存では、GPUの搭載したPCでは1秒間で何億個も試せます。 メリットである「速く大量に計算する」ことがパスワード保存では致命的な欠陥になります パスワード保存には`bcrypt / Argon2`といったパスワードハッシュのアルゴリズムを利用しましょう。 #### ハッシュ関係の代表的な攻撃一覧 | 攻撃名 | 概要 | 主な影響 | | --------------------------- | ------------------------ | --------------------- | | 総当たり攻撃(Brute Force) | 全パターン試行 | 弱いPWは即破られる | | 辞書攻撃 | よくあるPWを試す | 人間由来PWに有効 | | レインボーテーブル | 事前計算表で逆引き | ソルトなしで致命的 | | 衝突攻撃 | 異なる入力で同一ハッシュ | 署名・証明書破壊 | | 長さ拡張攻撃 | ハッシュ構造の欠陥利用 | MACの偽造 | | ハッシュ再利用 | 同一PW判定 | ユーザー特定 | | 高速ハッシュ悪用 | GPU大量試行 | SHA系PW保存破壊 | | パラメータ弱体化 | cost等が低すぎ | bcrypt/Argon2でも危険 | #### CVEの対応表 **総当たり・辞書攻撃系** | 攻撃 | 対象 | CVE / 事例 | | ----------- | ------------- | ------------------------------- | | 総当たり | SHA-1 / MD5 | CVE-2012-2122(弱ハッシュ比較) | | 辞書攻撃 | unsalted hash | LinkedIn 2012 パスワード流出 | | GPU総当たり | SHA-256 | Adobe 2013(高速ハッシュ使用) | * CVEより「設計ミス」扱いが多い * ハッシュ自体ではなく「使い方の問題」 **レインボーテーブル攻撃** | 攻撃 | 条件 | CVE / 事例 | | ------------------ | ---------- | ----------------------- | | レインボーテーブル | ソルトなし | CVE-2016-6316(Drupal) | | 同一ソルト | 固定ソルト | 複数CMS事例あり | ``` hash = SHA256(password + "fixed_salt") → 全ユーザーで同じ → 無意味 ``` **衝突攻撃(非常に重要)** | アルゴリズム | CVE / 事例 | 内容 | | ------------ | ---------------- | ---------- | | MD5 | CVE-2008-0166 | 証明書偽造 | | SHA-1 | SHAttered (2017) | 実衝突生成 | | SHA-1 | CVE-2017-15361 | Git影響 | * 電子署名 * 証明書 * ソフト配布の信頼性 **長さ拡張攻撃** | 対象 | CVE / 事例 | | ------- | -------------------------- | | MD5 | CVE-2011-3389(BEAST派生) | | SHA-1 | Web API署名偽造 | | SHA-256 | 独自MAC実装 | 脆弱な設計 ```ini MAC = SHA256(secret + message) ``` 正しい設計 ```ini MAC = HMAC-SHA256(secret, message) ``` **crypt / Argon2 関係の攻撃・CVE** bcrypt | CVE | 内容 | | ------------- | -------------- | | CVE-2011-2483 | bcrypt実装バグ | | CVE-2019-9193 | cost低設定問題 | ※アルゴリズム破壊ではなく 実装 or 設定ミス Argon2 | CVE | 内容 | | -------------- | ------------------- | | CVE-2020-28928 | Argon2ライブラリDoS | | CVE-2023-29491 | メモリ設定不備 | **ハッシュ比較のミス(地味だが致命的)** | 攻撃 | CVE | | -------------- | ------------- | | タイミング攻撃 | CVE-2009-4487 | | strcmp比較 | PHP系で多数 | 悪い例 ```php if ($hash1 == $hash2) ``` 正しい実装 ```php hash_equals($hash1, $hash2) ``` 理由: 比較処理の「実行時間」が情報になる ``` 1文字目一致? → 次へ 2文字目一致? → 次へ 違った時点で終了 ... 上記を狙ってレスポンス時間を測定して正解文字を探していく #### 実務でよくあるパターン | ミス | 結果 | | --------------- | ------------ | | SHA-256でPW保存 | GPU総当たり | | ソルト固定 | 全滅 | | cost低すぎ | 実質無防備 | | 独自ハッシュ | 高確率で破綻 | | MAC自作 | 署名偽造 | costとは: ハッシュ計算を「どれだけ重く・遅くするか」を決めるパラメータです。 ```sh cost = 10 → 約 2^10 = 1,024 回 cost = 12 → 約 2^12 = 4,096 回 cost = 14 → 約 2^14 = 16,384 回 ```