漏えいのお詫び文に、よくこう書いてあります。「パスワードは暗号化して保存していました」。読んだ側は少し安心します。しかし、この一文が意味するところは、やり方によって天と地ほど違います。同じ「暗号化」でも、数秒で元に戻せるものと、何年かけても戻せないものがある。本記事では、パスワードの「ハッシュ化」を、ただのハッシュ、ソルト付き、遅い方式の3段階に分けて、何が違うのかを図なしで説明します。後半は、お詫び文の読み方と、システムを発注する側が聞くべき一言です。
ハッシュ化とは何か——元に戻せない変換
ハッシュ化は、どんな長さの文字列からも、決まった長さの英数字の列(ハッシュ値)を作る計算です。「password123」を SHA-256 という方式でハッシュ化すると、64桁の英数字になります。この計算は一方通行で、ハッシュ値から元の文字列を計算で戻すことはできません。だからサービスは、パスワードそのものではなく、このハッシュ値だけを保存します。ログインのときは、入力されたパスワードを同じ方式でハッシュ化し、保存してあるハッシュ値と一致するかを比べます。
ここまでは正しい設計です。問題は、このハッシュ値に、ひとつ厄介な性質があることです。
ただのハッシュ——同じ暗号は、同じ答え
ハッシュ化は決まった計算なので、同じパスワードからは、世界中どこで計算しても同じ値が出ます。利用者Aの「password123」も、利用者Bの「password123」も、同じ64桁になります。
攻撃者はここを突きます。よく使われるパスワードを数億個集め、あらかじめ全部ハッシュ化した「答えの表」を作っておく。漏れたデータベースのハッシュ値をこの表と照合すれば、計算なしで元のパスワードが分かります。この表はレインボーテーブルと呼ばれ、主要な方式のものはインターネットで配布されています。1つの表で、漏れた700万人分を一度に照合できるのが、ただのハッシュの弱点です。
さらに、同じハッシュ値が並んでいれば「この人たちは同じパスワードを使っている」ことも分かります。使われている数が多いハッシュ値ほど、よくあるパスワードである可能性が高い。表がなくても、推測の手がかりになります。
ソルト付きハッシュ——全員、違う答えにする
対策は単純です。ハッシュ化する前に、利用者ごとにランダムな値を足す。この値をソルト(塩)と呼びます。利用者Aには「x7Qp」を、利用者Bには「m2Lk」を足してからハッシュ化すると、同じ「password123」でも、出てくるハッシュ値は全員違います。あらかじめ作った表は、ソルトの分だけずれるので、まったく効きません。
ただのハッシュ
| 利用者A password123 | ef92b778ba… |
| 利用者B password123 | ef92b778ba… |
| 利用者C password123 | ef92b778ba… |
同じパスワードは同じ値になる。よくあるパスワードの表(レインボーテーブル)と照合すれば、一瞬で逆引きできる
ソルト付きハッシュ
| 利用者A password123 | 0e2cc8346a… |
| 利用者B password123 | f613898433… |
| 利用者C password123 | 93500a0969… |
利用者ごとにランダムな値(ソルト)を足してからハッシュ化。同じパスワードでも全員違う値になり、表が効かない
値は SHA-256 で実際に計算したハッシュ値の先頭10桁。ソルトは「x7Qp」「m2Lk」「z9Rw」。
ここでいつも出る疑問が「ソルトを足したら、どうやって照合するのか」です。答えは、ソルトは秘密ではなく、ハッシュ値と並べてデータベースに保存しておく、です。ログイン時は、保存してあるソルトを取り出し、入力されたパスワードに同じように足して、同じ方式でハッシュ化し、保存してあるハッシュ値と比べます。パスワードそのものはどこにも保存されていないまま、「同じ材料から同じ計算をすれば同じ答えになる」ことだけを確かめています。
ソルトも盗まれたら?
データベースが漏れれば、ソルトもハッシュ値も一緒に攻撃者の手に渡ります。それでも守りが成り立つ理由を、攻撃者の立場で考えると分かります。
攻撃者が持っているのは、ソルト「x7Qp」とハッシュ値です。ここからパスワードを知る方法は1つしかありません。候補を1つ選び、「x7Qp」を足してハッシュ化し、ハッシュ値と一致するか見る。一致するまで繰り返す。つまり総当たりです。ソルトが効いているのは、この総当たりが利用者ごとにやり直しになる点です。利用者Aのソルトで計算した結果は、利用者Bには使えません。700万人分を一度に照合できた「ただのハッシュ」に対し、700万回やり直すことになります。
ただし、ソルトだけでは足りません。SHA-256 のような方式は、速く計算できるように作られています。市販のGPU 1枚(RTX 4090)で、SHA-256 は毎秒約220億回計算できます。1人分の総当たりでも、「password123」のようによくある候補なら、最初の数秒で当たります。ソルトが防ぐのは「全員まとめて」であって、「1人ずつ」は防げません。
出典: hashcat v6.2.6 benchmark on NVIDIA RTX 4090(MD5 164.1 GH/s、SHA2-256 21,975.5 MH/s、bcrypt 184.0 kH/s)
遅いハッシュ——1回の計算に、わざと時間をかける
そこで、パスワード専用の方式を使います。bcrypt、scrypt、Argon2、PBKDF2 といった名前のもので、共通しているのは1回の計算にわざと時間とメモリを使わせることです。同じGPUで、bcrypt は毎秒約18万回。SHA-256 の約12万分の1です。計算の重さは設定で上げられるので、サーバーが1回のログインに0.1秒かける設定なら、攻撃者が1人分の候補1億個を試すのに100日以上かかります。Argon2 はメモリも大量に使うため、GPUで並列に回しても速くなりません。
どれをどの設定で使うかは、OWASP(Webセキュリティの業界団体)が「パスワード保存のチートシート」として公開しています。2026年時点の推奨は、Argon2id(メモリ19MiB以上、繰り返し2回、並列1)を第一に、使えなければ scrypt、古いシステムでは bcrypt(コスト10以上)、FIPS 準拠が必要な場合は PBKDF2-HMAC-SHA256(60万回以上)です。これらの方式は、ソルトの生成と保存まで含めて1つの仕組みになっていて、出力される文字列の中に方式・設定・ソルト・ハッシュ値がまとめて入ります。開発者がソルトを別に管理する必要はありません。
出典: OWASP「Password Storage Cheat Sheet」
それでも、「password」や「123456」のように候補の最初の数個に入るパスワードは、どんな方式でも最初の一撃で当たります。方式はサービス側の責任、推測されにくいパスワードを使い回さないのは利用者側の責任、と役割が分かれています。
上乗せとして、データベースとは別の場所に置いた共通の秘密値(ペッパー)を全員分に足す方法もあります。データベースだけが漏れた場合には、ハッシュ値の照合すらできなくなります。ただし、ペッパーが一緒に漏れれば効果はなくなるので、ソルトの代わりではなく追加の防御として使います。
お詫び文の「暗号化」を、どう読むか
ここまでを踏まえて、この秋の漏えいのお詫び文を読み直すと、書き方に幅があることに気づきます。
- 「ハッシュ化したパスワード」(リンツ&シュプルングリージャパン、10月23日)、「不可逆暗号化されたパスワード」(花キューピット、10月28日):一方通行の変換をしていることは分かります。ソルトの有無と方式までは書かれていません。
- 「暗号化されたパスワード」(ノジマ、11月2日。アイリスオーヤマ、11月5日):ハッシュ化なのか、鍵があれば戻せる暗号化なのか、文面からは判断できません。
- 「暗号化せずに保存していた」(日本成令「AI Lab 225」、10月23日):正直な公表ですが、約19,250件のパスワードがそのまま読める状態で漏れたおそれがあります。
利用者としてできることは、方式が分からない以上、同じパスワードを使い回していた他のサービスから先に変えることです。方式が強くても、よくあるパスワードは当たります。方式が弱ければ、全部当たります。どちらにしても、使い回しがいちばんの被害経路です。
出典: リンツ&シュプルングリージャパン(2026年10月23日)/花キューピット(2026年10月28日)/ノジマ(2026年11月2日)/日本成令(2026年10月23日)
発注する側が、聞くべき一言
自社のサービスを作るとき、あるいは既存のシステムを引き継ぐとき、開発会社に聞く質問はひとつで足ります。「パスワードは、どの方式で、どんな設定で保存していますか」。答えが「Argon2id です」「bcrypt のコスト12です」なら健全です。「暗号化しています」「ハッシュ化しています」で止まる答えなら、方式と設定を確認してください。「SHA-256 です」なら、ソルトの有無にかかわらず、遅い方式への移行を計画する必要があります。
移行は、全員に再登録を求めなくてもできます。次にログインしたときに、入力されたパスワードを新しい方式でハッシュ化し直して保存すればよいからです。古い方式のまま残っている利用者には、一定期間後にパスワードの再設定を求めます。
私たちが公開しているpasskey-auth-starterでは、パスワードを Argon2id で保存し、そもそもパスワードを預からないパスキーを最初から選べるようにしています。「同じ暗号は、同じ答え」にならない設計を、コードと解説で確認できます。
まとめ
ただのハッシュは、同じパスワードが同じ値になるため、表で一度に逆引きできます。ソルトを足せば全員違う値になり、表が効かなくなります。ソルトごと盗まれても、総当たりは利用者ごとのやり直しになりますが、速い方式では1人分なら数秒で当たります。だから、わざと遅い方式(Argon2id、bcrypt)が要ります。お詫び文の「暗号化」は、この3段階のどこなのかを教えてくれません。利用者は使い回しを断ち、発注側は方式と設定を一言で聞く。それだけで、漏えいしたときの被害の大きさが変わります。
「暗号化しています」で止まらない設計を。
JumpStackは、お客さまの現場にAIチームを配置するFDEを軸に、課題の定義から実装・運用までをご一緒しています。認証の持ち方、パスワード保存方式の移行、パスキー導入まで、設計から見直します。
認証の設計を相談する