「ユーザーのパスワード、データベースにどう保存するのが正解?」——これはサービスを作る人が必ず一度ぶつかる問いです。答えははっきりしています。攻撃手順には触れず、安全な保存のしかただけを順番に解説します。
なぜ平文・暗号化・素のハッシュがダメなのか
データベースはいつか漏れる前提で考えます。そのとき、保存方式ごとに被害がまるで違います。
- 平文:漏れた瞬間に全パスワードが筒抜け。さらに使い回しにより、利用者の他サービスまで連鎖的に乗っ取られる。最悪。
- 暗号化(可逆):鍵があれば元に戻せる=鍵が一緒に漏れれば平文と同じ。パスワードは読み返す必要がないので、そもそも可逆である意味がない。
- 素のハッシュ(MD5/SHA-256):速いハッシュは、攻撃者が大量の候補を高速に試せる。よくあるパスワードはレインボーテーブルや総当たりで戻されてしまう。
安全になるまでの“4段階”
考え方は、弱い方式に一手ずつ対策を足していく流れで理解すると早いです。
ポイントは、ソルトと低速ハッシュは役割が違うことです。ソルトは「事前計算(レインボーテーブル)と使い回し一括解析」を無効にする。低速ハッシュは「総当たりの速度を現実的でないレベルに落とす」。両方そろって初めて安全になります(→ ハッシュ化とは)。
実践:今やること
Argon2id(または bcrypt)を使う
新規なら Argon2id を第一候補に。メモリ消費も要求できるためGPU総当たりに強い。既存の枯れた実装を重視するなら bcrypt でも実用上十分。どちらも標準ライブラリの実装をそのまま使う。
ソルトは“自動”に任せる
bcrypt/Argon2 は、利用者ごとのソルトを自動生成し、ハッシュ文字列の中に同梱する。自分でソルト列を持つ必要はない。手で MD5(salt + password) を組むのは、やってはいけない典型。
コスト(強度)を環境に合わせて設定する
bcrypt のコスト係数、Argon2 のメモリ・反復・並列度を、正規ログインが体感で気にならない範囲で最大になるよう設定する。サーバーが速くなるほど攻撃者も速くなるので、年単位で見直して引き上げる。
検証は標準の照合関数で
ログイン時は、保存済みハッシュと入力をライブラリの照合関数で突き合わせる(多くがタイミング差に配慮した定数時間比較になっている)。自前で文字列一致を書かない。
弱いハッシュは“ログイン時に再ハッシュ”で移行
既に MD5/SHA-256 で保存済みなら、ユーザーがログイン成功した瞬間に新方式で再ハッシュして保存し直す。未ログイン分は、既存ハッシュを bcrypt 等で包み直す二重ハッシュで暫定的に底上げできる。
やりがちな失敗 vs 正しい実装
やりがち
- パスワードを暗号化して保存(鍵が漏れたら終わり)
MD5(password)やSHA-256(password)をそのまま保存- 全ユーザー共通のソルトを1個だけ使う
- 自前で
hash(salt + password)を手組み
正しい実装
- Argon2id / bcrypt で一方向ハッシュ
- ソルトは利用者ごと(ライブラリが自動付与)
- コストは体感OKな範囲で最大、定期的に引き上げ
- 標準のハッシュ/照合関数をそのまま使う
当サイトの視点:パスワード保存は“枯れた正解”に乗る場所
パスワード保存は、独自性を出してよい領域ではありません。世界中で検証された Argon2/bcrypt の標準実装に素直に乗るのが、最も安全で、運用も楽です。当サイトの立場は「ここで創意工夫しない」。むしろ力を入れるべきは、そもそもパスワード依存を減らすこと——多要素認証(MFA)の徹底や、将来的なパスキー(パスワードレス)への移行です。最強のハッシュでも、弱いパスワードと使い回しは守り切れません。
次に読む
- 用語:パスワードのハッシュ化とは / ソルトとは
- 入門:パスワードの正しい保管(利用者側) / パスワードマネージャーの選び方
- 対策:二要素認証(MFA)の選び方(パスワード依存を減らす)
よくある質問
Qパスワードは暗号化して保存すればいいですか?
いいえ、暗号化は不向きです。暗号化は鍵があれば元に戻せる(復号できる)ので、鍵が漏れれば全パスワードが平文に戻ります。パスワードは運営側でも読み返す必要がないため、元に戻せない『ハッシュ化』が正解です。ただし素のハッシュでは不十分で、ユーザーごとのソルトと低速ハッシュ(bcrypt/Argon2)を組み合わせます。
Qbcrypt と Argon2、どちらを使うべきですか?
新規開発なら Argon2(特に Argon2id)が第一候補です。メモリと計算量の両方を調整でき、GPUでの総当たりに強いためです。既存資産や枯れた実装を重視するなら bcrypt も十分実用的です。重要なのは、どちらも『標準ライブラリの実装をそのまま使い、自前で組まない』ことです。
QすでにMD5やSHA-256で保存してしまっています。どう移行しますか?
一括で平文に戻すことはできない(それが利点)ので、ログイン時に移行します。ユーザーがログインに成功した瞬間、入力された正しいパスワードを新方式(Argon2id等)で再ハッシュして保存し直します。未ログインのユーザーは、既存ハッシュを bcrypt 等で“包み直す”二重ハッシュで暫定的に底上げする方法もあります。