用語辞典11分で読める

ソルト(salt)とは:パスワードのハッシュ化でユーザーごとに加えるランダムな値

ソルトは、パスワードをハッシュ化する前に足す、利用者ごとに違うランダムな値です。必要な理由、レインボーテーブルが無効になる仕組み、ペッパーとの違い、よくある誤解を解説します。

本文を読む
公開日
更新日
目次

パスワードのハッシュ化で必ず出てくる「ソルト」。ハッシュ化の前にランダムな値を1つ加えるだけで、安全性が大きく変わります。仕組みと注意点を解説します(攻撃手順は載せません)。

なぜソルトで安全になるのか

ソルトなしだと、同じパスワードの人は保存されるハッシュも同じになります。これにより、攻撃者は2つの方法を使えます。事前計算した対応表(レインボーテーブル)でそのまま元のパスワードを調べること、そして1人分の解析結果を同じパスワードの全員に使い回すことです。

ソルトを足すと、同じ "password123" でも保存値が利用者ごとにまったく別物になります。

ソルトなし:「password123」→ 全員 同じハッシュ(表で一発)
↓ 利用者ごとのソルトを足すと
Aさん:salt_a + password123 → ハッシュ X
Bさん:salt_b + password123 → ハッシュ Y(Xと別物)
同じパスワードでも、ソルトが違えば保存値は全員バラバラ。事前計算の表が効かなくなる。

同じ理屈で、ソルトは利用者ごと(できればパスワードごと)に新しく作る必要があります。全員で同じソルトを使い回すと、同じパスワードの人どうしの保存値がまた一致してしまい、せっかくの効果が薄れます。生成には、推測されにくい暗号学的な乱数を使い、作ったソルトはハッシュ値と一緒に保存します(秘密にする必要はありません)。

なお、ソルトが守るのは「事前計算した表」と「使い回しの一括解析」までです。1つのパスワードを総当たりで狙う攻撃そのものを遅くするのはソルトの仕事ではなく、bcrypt/Argon2 のようなわざと遅いハッシュが担います。両者は守備範囲が違うので、必ずセットで使います。

ソルトの長さと作り方

基準になる文書は次の2つです。

  • NIST SP 800-63B-4(米国の認証ガイドライン):ソルトは32ビット以上で、保存済みのソルトどうしが重なりにくいように選ぶ。ソルトとハッシュ値は、パスワードごとに両方保存する
  • RFC 9106(Argon2の仕様):パスワード用のソルトは16バイト(128ビット)を推奨。容量に制約がある場合は64ビットまで減らせる

作り方で守ることは3つです。

  • 暗号学的な乱数で作る:言語の安全な乱数関数を使います。Math.random() やPHPの mt_rand() のような、予測できる乱数は使いません
  • 推測できる値を使わない:ユーザー名、メールアドレス、ユーザーID、登録日時はソルトの代わりになりません
  • パスワードを変えたら、ソルトも作り直す:古いソルトを使い続けると、新旧のハッシュを結びつける手がかりが残ります

実際には、bcrypt・Argon2・scrypt の標準実装がこれらを自動で満たします。自分でソルトを作るコードを書いているなら、それ自体を見直す合図です。

ソルト・ペッパー・ストレッチングの違い

パスワード保存では、似た名前の対策が3つ出てきます。守る相手が違うので、どれかがほかの代わりにはなりません。

ソルトペッパーストレッチング(低速化)
何か利用者ごとのランダムな値全体に共通の秘密の値ハッシュ計算をわざと重くすること
秘密にするかしない(ハッシュと一緒に保存)する(DBとは別の場所に保管)設定値は秘密でなくてよい
防ぐもの事前計算した表、同じパスワードの一括解析DBだけが漏れたときの解析1件ずつの総当たり
実装bcrypt/Argon2が自動で付ける必要に応じて自分で追加bcryptのコスト、Argon2のメモリ・反復回数

NIST SP 800-63B-4 は、ペッパーにあたる「検証側だけが知る秘密鍵」をパスワードのハッシュとは別に保管すること(できればHSMなどの専用ハードウェア内)を推奨しています。

具体例:ソルトなしの保存が問題になったLinkedIn(2012年)

2012年6月、LinkedInの利用者のものとされる約650万件のパスワードのハッシュ値がネット上に公開されたと報じられました。LinkedInは、流出したものの一部が自社アカウントのパスワードに該当することを認め、該当する利用者のパスワードを無効にしました。

同社は公式ブログで、パスワードを「ハッシュ化するだけの方式」から「ハッシュ化とソルトの両方を行う方式」へ移行を進めていたと説明しています。当時の報道では、同社がパスワードの保護にSHA-1によるハッシュ化だけを使っていたことが専門家から批判されました。

この事例から分かることは2つです。

  • ソルトなしのハッシュは、よくあるパスワードほど事前計算の表で一度に戻される
  • 移行を始めていても、古い方式のハッシュが残っていれば、漏れたときの被害はその方式で決まる

自分の環境で確認する方法

1

保存されている文字列の形を見る

自分が管理する開発環境のデータベースで、パスワード欄を数件確認します。bcrypt なら $2b$12$ のあとの22文字がソルトです。Argon2 なら $argon2id$v=19$m=…,t=…,p=…$ のあとに「ソルト」と「ハッシュ」が $ で区切られて並びます。どちらの形でもなく、別の列にもソルトが見当たらない場合は、ソルトなしで保存されている可能性があります。

2

同じパスワードで2つのテスト用アカウントを作る

開発環境で、同じパスワードのテスト用アカウントを2つ登録し、保存された値を比べます。値が一致したら、ソルトが効いていません。パスワードを変更したときにソルト部分も変わるかも、あわせて確認します。

3

ソルトを自分で作っているコードを探す

コード内で salt という語や、乱数・ハッシュ関数を手で組み合わせている箇所を探します。予測できる乱数、ユーザー名やIDの流用、固定文字列が見つかったら、言語やフレームワークの標準パスワード関数に置き換えます。

4

移行の方法は実践ガイドで確認する

ソルトなしの保存が見つかったときの移行手順(ログイン時の再ハッシュなど)と、方式ごとの推奨設定値は、パスワードの安全な保存方法にまとめています。

よくある誤解と正解

誤解

  • ソルトは秘密にしないといけない
  • 全ユーザー共通のソルトでいい
  • ソルトを足せば弱いパスワードでも安全

正解

  • ソルトは公開前提でOK(ハッシュと一緒に保存)
  • 利用者ごと(できればパスワードごと)に別の乱数
  • ソルトは“事前計算と使い回し解析”対策。総当たり対策は低速ハッシュが担う

当サイトの視点:まずはソルトと低速ハッシュを正しく使う

ペッパーは、データベースだけが盗まれた場合に備える追加の対策です。秘密の値を別の場所で管理する手間が増え、その値をなくすと全員のパスワードを照合できなくなります。

そのため実務では、まず bcrypt/Argon2 によるソルト+低速ハッシュを正しく使うことが先決です。ペッパーは、鍵の管理の仕組みがすでにある場合に検討します。

出典(一次情報)

  • NIST「SP 800-63B-4 Digital Identity Guidelines: Authentication and Authenticator Management」(2025年8月) — pages.nist.gov(ソルトは32ビット以上、ソルトとハッシュの保存、別に保管する秘密鍵)
  • RFC 9106「Argon2 Memory-Hard Function for Password Hashing and Proof-of-Work Applications」 — rfc-editor.org(パスワード用ソルトは16バイト推奨)
  • OWASP「Password Storage Cheat Sheet」 — cheatsheetseries.owasp.org(ソルト、ペッパー、多くのライブラリがソルトを自動で扱うこと)
  • PHC string format(Argon2などのハッシュ文字列の形式) — github.com/P-H-C
  • TechCrunch「LinkedIn Confirms Hack And Leak Of "Some" User Passwords」(2012年6月6日) — techcrunch.com(約650万件、ハッシュ化とソルトへの移行についての同社の説明)
  • Computerworld「LinkedIn provides breach update -- sort of」(2012年6月8日) — computerworld.com(SHA-1だけのハッシュ化への批判、パスワードの無効化)

次に読む

分類番号

CWE は脆弱性の原因となる弱点の種類を、MITRE ATT&CK は攻撃者の手口を分類した番号体系です。どちらも MITRE が管理し、脆弱性情報や検知ルールの分類に広く使われています。

ATT&CK(攻撃の手口)

CWE™: Copyright © 2006–2026, The MITRE Corporation. CWE is a trademark of The MITRE Corporation. The MITRE Corporation hereby grants you a non-exclusive, royalty-free license to use CWE for research, development, and commercial purposes. Any copy you make for such purposes is authorized on the condition that you reproduce MITRE’s copyright designation and this license in any such copy. CWE Terms of Use

© 2026 The MITRE Corporation. This work is reproduced and distributed with the permission of The MITRE Corporation. MITRE ATT&CK and ATT&CK are registered trademarks of The MITRE Corporation. The MITRE Corporation (MITRE) hereby grants you a non-exclusive, royalty-free license to use ATT&CK® for research, development, and commercial purposes. Any copy you make for such purposes is authorized provided that you reproduce MITRE's copyright designation and this license in any such copy. ATT&CK Terms of Use

よくある質問

Qソルトは秘密にしないといけませんか?
A

いいえ。ソルトは『秘密の鍵』ではなく、ハッシュ値と一緒に保存して構いません。目的は秘匿ではなく、同じパスワードでも保存値を全員バラバラにして、事前計算(レインボーテーブル)や使い回しの一括解析を無効にすることです。秘密にすべきなのは別物の『ペッパー』(後述)です。

Q全ユーザーで同じソルトを使い回してもいいですか?
A

ダメです。ソルトは利用者ごと(できればパスワードごと)に異なるランダム値であることが肝心です。共通ソルトだと、同じパスワードの人どうしの保存値が一致してしまい、攻撃者は1回の総当たりで複数アカウントをまとめて破れます。新規生成のたびに暗号学的乱数で作ります。

Q自分でソルトを実装する必要がありますか?
A

ふつうは不要です。bcrypt・Argon2・scrypt といった専用ハッシュは、ソルトの生成と保存(多くはハッシュ文字列の中に同梱)を自動で行います。自前でソルトを足すより、これら標準実装に任せるのが安全で確実です。

Qレインボーテーブルとは何ですか?
A

よく使われるパスワードと、そのハッシュ値の対応を前もって大量に計算しておいた表です。ソルトなしで保存されたハッシュは、この表を引くだけで元のパスワードが分かってしまいます。ソルトを足すと、表を作る時点でソルトの値が分からないため、事前計算した表が使えなくなります。

Qソルトの長さはどれくらい必要ですか?
A

NISTのSP 800-63B-4は32ビット以上を求めています。Argon2の仕様(RFC 9106)はパスワード用に16バイト(128ビット)を推奨しています。bcryptやArgon2の標準実装は十分な長さのソルトを自動で作るので、自分で長さを決める場面はほとんどありません。

Qユーザー名やユーザーIDをソルトにしてもいいですか?
A

おすすめしません。ユーザー名やIDは推測でき、ほかのサービスでも同じ値(例:admin)が使われるため、その値向けの表を前もって作られる余地が残ります。また、パスワードを変えてもソルトが変わりません。ソルトは暗号学的な乱数で、パスワードを設定するたびに新しく作ります。