Dev Study
← セキュリティとAIの仕組み
レッスン 7 / 13·約 9 分·第4期 セキュリティとAIの仕組み

なぜハッシュは戻せないのか — 一方向性と保存

リクエストがアプリケーションに届くまで
  1. ブラウザURL入力
  2. DNS名前→IP
  3. ルータ経路選択
  4. ロードバランサ振り分け
  5. Nginx受け口今ここ
  6. アプリ処理今ここ
  7. DB保存

前回、認証が「主張された属性値を検証する」過程だと見ました。パスワードによる認証では、その検証のために何かを保存しておく必要があります。何を保存するかが今回の主題です。

まず結論

パスワードを保存するとき、後から元に戻せないことが要件になります。NIST SP 800-63B-4 は「オフライン攻撃に耐える形で保存する」「ソルトを付けてハッシュする」を **SHALL** で求めています。

ソルトの目的は「レインボーテーブル対策」だけではありません。RFC 4949 の定義はもっと一般的で、**ある1件への計算結果を別の1件へ再利用できなくする**ことです。事前計算表が効かなくなるのは、その結果のひとつです。

? 読む前に予測

NIST SP 800-63B-4(2025年、Final)は、パスワードの定期変更を強制することについてどう規定しているでしょうか。

当てることが目的ではありません。外した予測ほど記憶に残るので、直感で選んでください。

抽象原理

戻せないことが、そのまま要件になっている

前回、認証は「主張された属性値を検証する」過程だと見ました。パスワードで検証するには、照合するための何かを保存しておく必要があります。

パスワードそのものを保存すると、保存場所を読めた者がすべてを手に入れます。そこで元に戻せない形で保存します。NIST SP 800-63B-4 はこれを SHALL で要求しています。

"Verifiers SHALL store passwords in a form that is resistant to offline attacks. Passwords SHALL be salted and hashed using a suitable password hashing scheme."

注目したいのは “resistant to offline attacks” という言い方です。「復元不可能」ではなく「オフライン攻撃に耐える」。保存されたものを手に入れた攻撃者が、自分の手元で好きなだけ試せる状況を想定しています。時間と計算資源をかけられる前提で、それでも割に合わないようにするというのが要件の形です。

だから「ハッシュ関数を使ったから安全」では足りません。総当たりが速く回せる関数では、オフラインで短時間に試し尽くされます。方式の選択が要件に含まれるのはこのためです。

✓ ここまでの確認

RFC 4949 が定義するソルト (salt) の目的として、最も正確なものはどれですか。

具体実物

ソルトが何をしているか

ソルトの説明として「レインボーテーブル対策」とよく言われます。間違いではありませんが、RFC 4949 の定義はもっと広く取っています。

"salt (I) A data value used to vary the results of a computation in a security mechanism, so that an exposed computational result from one instance of applying the mechanism cannot be reused by an attacker in another instance."

この定義にレインボーテーブルは出てきません。言っているのは「1件の結果を、別の1件に再利用できなくする」ことです。

ソルトが無い場合と、ある場合に何が変わるか
ソルト無し同じパスワードなら同じ結果になる× 1件の計算が全件に使える
ソルトあり1件ごとに結果が変わる○ 計算を使い回せない
帰結事前計算表(レインボーテーブル)が効かない○ 目的ではなく結果
↓
目的は「再利用させないこと」。事前計算表が無効になるのは、そこから出てくる帰結のひとつ
  • ・RFC 4949 の定義文はレインボーテーブルに言及していない
  • ・SP 800-63B-4 はソルトを32ビット以上とし、保存済みハッシュ間の衝突を最小化するよう選ぶことを SHALL とする

OWASP の説明も同じ方向を向いています。

"An attacker has to crack hashes one at a time using the respective salt rather than calculating a hash once and comparing it against every stored hash."

1回計算して全件と突き合わせることができなくなる。これが核心です。レインボーテーブルは「1回の計算を使い回す」手口の一例にすぎず、目的そのものではありません。

✓ ここまでの確認

NIST SP 800-63B-4 は、パスワードハッシュのアルゴリズムとして Argon2 や bcrypt を名指しして推奨していますか。

⇄ 2つを見比べる
具体例 A

ソルト — 保存されたハッシュを個別化する

ソルトを1件ごとに変えると、同じパスワードでも保存される値が変わります。攻撃側は1件ずつ計算しなければならず、1回の計算結果を他の行へ当てはめることができません。費用が件数に比例します。

攻撃側の費用の変化表
ソルト無し: 計算1回 → 全件と照合できる
ソルトあり: 計算1回 → その1件にしか使えない
具体例 B

鍵の個別化 — 1本の鍵で全部を開けさせない(第44週)

第44週で見たとおり、TLS 1.3 が静的な鍵交換を削除した理由として挙げられたのは forward secrecy でした。鍵を毎回作り直せば、1本が破られたときに影響が他へ及びません。ここでも「1つの成果が全体に及ばないようにする」構造が使われています。

RFC 8446 が削除の理由に挙げたもの表
all public-key based key exchange mechanisms
now provide forward secrecy

ソルトによる個別化と、鍵の使い回しを避ける設計。この2つに共通する考え方は何でしょうか。

攻撃側が1回の成功から何を得られるか、という観点で比べてみてください。

この章のまとめ

  • 保存の要件は「復元不可能」ではなく “resistant to offline attacks”。攻撃者が手元で好きなだけ試せる前提で、割に合わなくする。
  • SP 800-63B-4 はパスワードをソルト付きでハッシュすることを SHALL とし、ソルトは32ビット以上、保存済みハッシュ間の衝突を最小化するよう選ぶ。
  • ソルトの目的はレインボーテーブル対策「だけ」ではない。 RFC 4949 の定義は「1件の計算結果を別の1件へ再利用させない」こと。事前計算表が効かなくなるのは帰結。
  • NIST SP 800-63B-4 は Argon2/bcrypt/scrypt/PBKDF2 を名指ししていない(委任先の SP 800-132 §5.3 が PBKDF2 を承認)。具体的な設定値は OWASP の文書にある。出典を分けて扱う。
  • 単一要素なら最小15文字(-4版)。多要素の一部としてのみ使う場合は8文字以上を許容してよい。
  • 定期変更の強制と構成規則の強制は SHALL NOT。 ただし侵害の証拠があれば変更を強制する SHALL。

自分の現場で確かめる

読んだだけでは身につきません。手元の環境で実際に見てみてください。

理解度チェック

読んだ直後は「分かった」と感じやすいものです。実際に解いて確かめてください。

問題 1 / 3正解: 0

「ソルトは秘密にしなければ意味がない」——この説明の評価として最も適切なものはどれですか。

用語集(4語)
ソルト (salt)
セキュリティ機構における計算結果を変化させるためのデータ値。ある1回の適用で露出した計算結果を、攻撃者が別の適用で再利用できないようにする(RFC 4949)。
オフライン攻撃に耐える保存
NIST SP 800-63B-4 が SHALL で求める保存形式。“Verifiers SHALL store passwords in a form that is resistant to offline attacks.” パスワードはソルトを付けて、適切なパスワードハッシュ方式でハッシュする。
ソルトの最小長
NIST SP 800-63B-4 は “The salt SHALL be at least 32 bits in length and chosen to minimize salt value collisions among stored hashes.” と定める。保存済みハッシュ間で値が衝突しにくいよう選ぶことまで含まれる。
鍵付きハッシュ(追加の一段)
検証者だけが知る秘密鍵を使う、鍵付きハッシュまたは暗号化の追加の一段(SP 800-63B-4)。その鍵はハッシュ済みパスワードとは分けて保存することが SHALL、ハードウェア保護領域での保存・使用が SHOULD とされる。