原文を取り出さずに一致を確かめる

通常のパスワード認証では、原文を残す代わりに、パスワード保存専用の関数で計算したハッシュを保存します。ログイン時も入力した値へ同じ条件で計算し、一致するかを確かめます。

ハッシュから原文を復元する機能は必要ありません。ただし攻撃者は、候補のパスワードを計算して照合できます。ハッシュにしただけで推測が不可能になるわけではありません。

参照:出典 s1

ソルトは同じパスワードの計算結果を分ける

ソルトはパスワードごとに用意して計算へ加えるランダムな値です。ハッシュと一緒に保存できます。秘密鍵と異なり、隠すことより、利用者ごとに異なる値を使うことが重要です。

同じパスワードを使う二人でも、別のソルトなら保存結果が異なります。攻撃者は全員に使い回す事前計算表を利用しにくくなります。一人分のソルトとハッシュを盗んだ後、その人の候補を試すことまでは防げません。

参照:出典 s1

一回の計算を重くして大量の推測を遅くする

SHA-256などの一般的な高速ハッシュをそのまま使うと、攻撃者も大量の候補を短時間で試せます。Argon2idなど、計算時間やメモリー使用量を調整できるパスワード保存専用の方式を使います。

コストは一回の照合に必要な計算量などの設定です。高くすると攻撃者の負担も増えますが、正規の処理も重くなります。現行推奨と自分の環境での計測を基に設定し、維持されているライブラリーを利用します。

参照:出典 s1

方式・設定・ソルト・計算結果を保持する

登録時にライブラリーのhash機能へパスワードを渡し、保存用文字列をデータベースへ保存します。方式、コスト、ソルト、ハッシュを含む形式なら、後の照合にも必要な条件を使えます。

次はライブラリーの具体的なAPIではない擬似コードです。ソルト生成や比較を独自実装せず、verifyで照合します。古いコストなら、認証成功時に再計算して更新する運用もできます。

説明用の通信例・設定例・擬似コード

// 登録
stored = passwordLibrary.hash(password)
database.save(userId, stored)

// ログイン
stored = database.load(userId)
if not passwordLibrary.verify(stored, submittedPassword):
    rejectLogin()

参照:出典 s1

流出後の推測と、ログイン画面への試行を分ける

データベースを盗んだ攻撃者は、自分の機械で候補を計算できます。オフラインの推測には、サイトのログイン回数制限は作用しません。専用ハッシュに加えて、十分に長く推測しにくいパスワードが重要です。

ログイン画面へ繰り返し送信するオンラインの試行には、回数制限、監視、多要素認証を組み合わせます。ペッパーという別管理の秘密を計算に組み込む設計もありますが、交換や復旧も必要です。ソルトと同じ場所へ置くだけでよいとは考えません。

参照:出典 s1

忘れたパスワードは復元せず再設定する

確認問題:保存済みパスワードをメールで送り返す設計は適切でしょうか。通常の認証では原文を取り出せない保存を使い、有効期限付きの手続きで新しい値へ変更します。

再設定用トークンは推測しにくく、一度使ったら無効にし、有効期限を設けます。変更後の既存セッションの扱いも決めます。保存方法だけで、認証や復旧の全体が安全になるわけではありません。

参照:出典 s1 / 出典 s2

出典・確認範囲

  1. [s1] Password Storage Cheat SheetOWASP / 確認日 2026-11-03
  2. [s2] Digital Identity Guidelines: Authentication and Authenticator ManagementNIST / SP 800-63B-4 / 確認日 2026-11-03
未確認事項・限界

通信例・設定例・被害の例は、仕組みを理解するための仮定です。特定の製品で発生した事件を示すものではありません。ブラウザやサービス固有の設定は、利用する環境の公式資料でも確認してください。