ソルトとは
この記事は約 2 分で読めます
ソルト (Salt) とは、パスワードをハッシュ化する際に付加するランダムなデータです。同じパスワードでもソルトが異なれば異なるハッシュ値が生成されるため、レインボーテーブル攻撃や事前計算攻撃を無効化できます。ソルトはユーザーごとに一意に生成され、ハッシュ値とともに保存されます。
ソルトの仕組みと数値例
パスワードのハッシュ化時に、暗号学的に安全な乱数生成器でソルトを生成し、パスワードと結合してからハッシュ関数に入力します。たとえば、パスワード「 mypassword 」に 16 バイト (128 ビット) のソルトを付加すると、同じパスワードでもユーザーごとに完全に異なるハッシュ値が生成されます。ソルトの推奨長は 16 バイト以上で、 bcrypt では 128 ビット、 Argon2 では 128 ビット以上が標準です。 2025 年時点の OWASP ガイドラインでは、 Argon2id と 16 バイト以上のソルトの組み合わせが推奨されています。ソルトは秘密にする必要はなく、ハッシュ値と一緒にデータベースに保存されます。重要なのは、ユーザーごとに異なるソルトを使用することです。
| ユーザー | ソルト (16 バイト・先頭 8 桁) | ハッシュ値の先頭 16 桁 |
|---|---|---|
| ユーザー A (ソルトなし) | なし | 89e01536ac207279... |
| ユーザー B (ソルトなし) | なし | 89e01536ac207279... |
| ユーザー A (ソルトあり) | 8f2b7c1d... | 58ef28c75d1f8e9e... |
| ユーザー B (ソルトあり) | 1a4c9e2b... | f8250873b0d4600e... |
ソルトなしの 2 行が同じ値になっている点が、レインボーテーブルが効いてしまう理由です。ユーザーごとに異なるソルトを付けた下の 2 行は、同じパスワードでも共通点のない値になります。
現場での使用例
「セキュリティ監査で、レガシーシステムのパスワード保存にソルトが使われていないことが発覚しました。 Argon2id + 16 バイトソルトへの移行を最優先タスクとして対応中です。」
なぜソルトが必要か
ソルトがなければ、同じパスワードを使うユーザーは全員同じハッシュ値になります。攻撃者はレインボーテーブルを使って一度に大量のパスワードを解読できてしまいます。具体的な数値で考えると、ソルトなしの場合、攻撃者は 1 つのレインボーテーブル (数百 GB 程度) で全ユーザーのパスワードを攻撃できます。しかし 16 バイトのソルトを使用すると、理論上 2 の 128 乗通りのテーブルが必要になり、事前計算攻撃は事実上不可能になります。
実務での落とし穴
よくある誤りは、全ユーザーに同じソルトを使用することです。これではレインボーテーブルの無効化効果が大幅に低下します。また、ソルトの長さが短すぎる (4 バイト以下など) 場合も、攻撃者が全ソルトパターンに対応したテーブルを作成できてしまいます。もう 1 つの落とし穴は、ソルトを「秘密」として別の場所に保管しようとすることです。ソルトの目的は秘匿ではなく一意性の確保であり、ハッシュ値と同じデータベースに保存して問題ありません。ランダムに生成したパスワードはそもそも推測が困難ですが、サービス側のソルト実装と組み合わせることで、より堅牢な保護が実現します。
この記事は役に立ちましたか?