ctf-training-lab/readme/暗号/ハッシュ値について.md

179 lines
6.1 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# ハッシュ値とは?
**一方向性**
元のデータからハッシュ値を簡単に計算できますが、
ハッシュ値から元のデータを再構築するのは非常に難しい(ほぼ不可能)です。
**固定長出力**
どんなサイズの入力データでも、ハッシュ関数は固定長の出力を生成します。
たとえば、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では秒間で何億個も試せます。
メリットである「速く大量に計算する」ことがパスワード保存では致命的な欠陥になります
パスワード保存には`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-6316Drupal |
| 同一ソルト | 固定ソルト | 複数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-3389BEAST派生 |
| 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 回
```