はじめに
最近、連日情報漏えいのニュースを目にします。
ニュースを見ていると「パスワードは平文で保存されていた」「ハッシュ化されていた」といった言葉がよく出てきます。
ただ、ハッシュ化って何なのか、暗号化と何が違うのかを聞かれると意外とうまく説明できない人も多いんじゃないでしょうか。
この記事ではハッシュ化と暗号化の違いをできるだけ噛み砕いて整理します。
最近の漏えい事案にも触れながら、なぜパスワードはハッシュ化して保存するのかまでをまとめます。
1. ハッシュ化とは
ハッシュ化とは、元のデータをハッシュ関数に通して決まった長さの文字列に変えることです。
変換後の文字列はハッシュ値と呼びます。
たとえば password という文字列をSHA-256(代表的なハッシュ関数のひとつ)にかけると、次の64文字になります。
5e884898da28047151d0e56f8dc6292773603d0d6aabbdd62a11ef721d1542d8
同じくMD5(古いハッシュ関数)なら32文字です。
5f4dcc3b5aa765d61d8327deb882cf99
ハッシュ関数には、覚えておきたい性質が3つあります。
- 一方向性:ハッシュ値から元のデータに戻せない
- 決定性:同じ入力なら、何回やっても同じハッシュ値になる
- 固定長:入力が短くても長くても、出力の長さは同じ
「一方向性」はミキサーにかけた果物をもとの形に戻せないようなイメージです。
でも同じ果物を同じ手順でかければ、同じ味のジュースができます。これが決定性です。
なぜ入力が何万文字でも、出力は同じ長さなのか
3つ目の固定長は、いちばん不思議に感じるところかもしれません。
1文字でも数万文字でもSHA-256なら出力は必ず64文字(256ビット)です。
どうやっているのかというと、仕組みはシンプルです。
SHA-256の場合、流れはこうなっています。
- 入力を64バイト(512ビット)ずつのブロックに区切る
- 最後のブロックが足りなければ、決まったルールで埋めて長さをそろえる(パディング)
- サイズが決まった作業用のメモ(256ビット)を用意しておく
- ブロックを1つ読み込むたびに、メモの中身をかき混ぜて書き換える
- 全部のブロックを読み終えたときのメモの中身が、そのままハッシュ値になる
ポイントは、メモのサイズが最初から最後まで変わらないことです。
入力が1文字ならブロックは1つで済みます。
入力が数万文字ならブロックが何百何千と続きます。
でも読み込む回数が増えるだけでメモの大きさは同じです。
だから最後に出てくるハッシュ値も、入力の長さに関係なく同じ長さになります。
イメージとしては大きさの決まった鍋です。
具材を少しだけ入れても山盛り入れても、鍋に入る量は決まっているので、できあがるスープの量は変わりません。
ただし具材が違えばスープの味は全然違うものになります。
長さが固定だと、なぜ元に戻せないのか
ここまで読むと一方向性の理由も見えてきます。
数万文字のデータをたった64文字の中に押し込んでいるわけです。
入力の情報のほとんどはかき混ぜる過程で失われます。
小さなメモの中身から元の長い入力を復元することはできません。
元に戻せないのは情報が圧縮されているからというのが、理由の一つです。
もう一つ、補足があります。
出力の長さが決まっているので出せるハッシュ値の種類にも上限があります。
SHA-256の場合は2の256乗通りです。
一方で入力のパターンは無限にあるので、違う入力が同じハッシュ値になること(衝突)は、理屈の上では必ず起こります。
ただ、SHA-256では衝突を意図的に見つけることは現実的に難しいとされています。
これに対してMD5は衝突を意図的に作れることが知られていて、セキュリティ用途では避けるべきとされています。
この章のまとめ
- 入力を一定サイズのブロックに区切り、固定サイズのメモをかき混ぜ続けるので、出力の長さは入力に左右されない
- 数万文字を数十文字に押し込むので、情報が失われて元に戻せない
- 出力の種類には上限があるので、衝突は理屈の上では起こりうる
2. 暗号化とは
暗号化とは、鍵を使ってデータを読めない形に変えることです。
鍵を持っている人だけがもとの形に戻せます。これを復号と呼びます。
イメージとしては鍵のかかった箱に手紙を入れる感じです。
鍵があれば開けて読めますが、鍵がなければ開けられません。
通信(HTTPSなど)やファイルの保護で使われているのは、こちらです。
3. ハッシュ化と暗号化の違い
一番の違いは元に戻せるかどうかです。
| 項目 | ハッシュ化 | 暗号化 |
|---|---|---|
| 元に戻せるか | 戻せない | 鍵があれば戻せる |
| 鍵 | 使わない | 使う |
| 主な目的 | 一致しているかの確認 | 内容を他人に読ませない |
| 向いている用途 | パスワードの保存・改ざん検知 | 通信の保護・保存データの秘匿 |
使い分けの目安はこうです。
- あとで中身を使いたいデータ(メール本文など)は、暗号化
- 一致しているかだけ分かればいいデータ(パスワードなど)は、ハッシュ化
この章のまとめ
- ハッシュ化は戻せない、暗号化は鍵があれば戻せる
- 目的も違うので、用途で使い分ける
4. なぜパスワードはハッシュ化して保存するのか
サービス側がパスワードを知っておく必要はありません。
ログインのときに「入力された値が、登録時の値と同じか」だけ分かれば足ります。
だから、次のような流れで保存と確認をします。
- 登録時:パスワードをハッシュ化して、ハッシュ値だけをDBに保存する
- ログイン時:入力されたパスワードをハッシュ化して、保存してある値と比べる
こうしておけばDBの中身が盗まれてもパスワードそのものはすぐには分かりません。
では暗号化して保存してもよさそうに見えますが、暗号化は鍵があれば戻せてしまいます。
鍵も一緒に盗まれたら、全員分のパスワードがそのまま読めてしまいます。
OWASP(Webセキュリティの国際的な非営利団体)のチートシートでも、パスワードは暗号化や平文ではなく、ハッシュ関数で保存することが勧められています。
ソルトという工夫
同じパスワードは同じハッシュ値になります。
すると、よくあるパスワードのハッシュ値を事前に計算した対応表(レインボーテーブル)で、逆引きされてしまいます。
そこでソルトを使います。
ソルトとは、ユーザーごとに違う使い捨てのランダムな文字列のことです。パスワードに混ぜてからハッシュ化します。
これで、対応表での逆引きや「同じパスワードの人がDB上で見分けられる」問題を防げます。
具体例で見てみる
2人のユーザーが、同じ password というパスワードを使っているとします。
ソルトなしで、SHA-256にかけた場合はこうなります。
| ユーザー | 入力 | 保存されるハッシュ値 |
|---|---|---|
| Aさん | password |
5e884898da28047151d0e56f8dc6292773603d0d6aabbdd62a11ef721d1542d8 |
| Bさん | password |
5e884898da28047151d0e56f8dc6292773603d0d6aabbdd62a11ef721d1542d8 |
同じ値が2つ並んでいます。
DBを見た人は、2人が同じパスワードだと一目で分かります。
しかもこの値は password のハッシュ値としてよく知られたものです。
対応表に載っているので、逆引きすれば元のパスワードがすぐ分かります。
次に、ユーザーごとにソルトを決めてパスワードの前に付けてからハッシュ化します。
ソルトはAさんが Ab3xK9pQ、Bさんが Zt7mW2vL だったとします。
| ユーザー | ソルト | 入力(ソルト+パスワード) | 保存されるハッシュ値 |
|---|---|---|---|
| Aさん | Ab3xK9pQ |
Ab3xK9pQpassword |
439eee839db8aeed1bb3b896a97a2ff358619f06b211bbd8e7df8d7e9f45d1a3 |
| Bさん | Zt7mW2vL |
Zt7mW2vLpassword |
3305966f0cf6d190337efd808823923e1e38026c9a59b4c4f73c1b0ffb5d6df2 |
元のパスワードは同じ password なのにハッシュ値はまったく別物になりました。
これで2つのことが防げます。
- 同じパスワードの人が見分けられない:DBを見ても、ハッシュ値が一致しないので同じパスワードかどうか分からない
-
対応表で逆引きできない:
Ab3xK9pQpasswordのような文字列は、事前に計算された対応表には載っていない
ログインのときは保存しておいたソルトを使って同じ計算をします。
Aさんが password を入力したら、Ab3xK9pQ を前に付けてハッシュ化し、保存値と一致するか比べます。
ほんの少しの違いで、結果は大きく変わる
ハッシュ関数には入力が少し違うだけで出力が大きく変わる性質もあります。
先ほどのAさんのソルトのまま、パスワードを password123 に変えてみます。
| 入力 | ハッシュ値 |
|---|---|
Ab3xK9pQpassword |
439eee839db8aeed1bb3b896a97a2ff358619f06b211bbd8e7df8d7e9f45d1a3 |
Ab3xK9pQpassword123 |
4aaf2714fe12d48083a00a0d361c50f8953eabe86116709649f89caaa560a7fc |
末尾に3文字足しただけで似たところが見当たらないほど別の値になっています。
入力から出力を推測する手がかりにならないので、この性質も一方向性を支えています。
この章のまとめ
- ソルトはユーザーごとに違う文字列で、パスワードに混ぜてからハッシュ化する
- 同じパスワードでも、ソルトが違えばハッシュ値はまったく別物になる
- ソルトは、ハッシュ値と一緒にDBへ保存しておく(ログイン時に同じ計算をするため)
5. 最近の漏えい事案と平文保存
最近の漏えい事案を見てみます。
KDDIのISP向けメールシステム
2026年6月に発覚したKDDIのISP事業者向けメールシステムへの不正アクセスについて、個人情報保護委員会が8月19日に行政上の対応を発表しています。
ScanNetSecurityによると、漏えいが確認された件数は次の通りです。
| 項目 | 件数 |
|---|---|
| メールアドレスの漏えいが確認された人数 | 1,223万1,954人 |
| うちパスワードの漏えいも確認された人数 | 761万6,173人 |
パスワードは平文のまま保存されており
参考:ScanNetSecurity「KDDI の ISP 事業者向けメールシステムに不正アクセス、個人情報保護委員会が行政指導」
7月の発表時点の件数は、PC Watchが報じています。
参考:PC Watch「KDDI、不正アクセスでメールアドレス1,223万名とパスワード761万名漏洩」
平文とは、暗号化もハッシュ化もされていない、そのまま読める状態のことです。
この状態で盗まれると、パスワードはそのままログインに使えてしまいます。
その後も続くパスワード漏えい
その後もパスワードを含む漏えいは続いています。
| 事案 | 公表時期 | パスワードに関する公表内容 |
|---|---|---|
| ショップサーブ(イーストア) | 2026年8月 | 会員IDとパスワードが漏えい対象に含まれる。保存形式は未公表 |
| ソースネクスト | 2026年10月15日 | 最大2251万9960件にパスワードを含む。保存形式は公式発表では未言及 |
ソースネクストの件では、INTERNET Watchが、パスワードのリセット対応などから平文で流出したとみられると伝えています。
平文で流出したとみられる
参考:INTERNET Watch「ソースネクスト、不正アクセスでパスワード含む会員の個人情報最大約2252万件が流出」
ただしこれは報道側の見立てで、公式発表が保存方式を明らかにしているわけではありません。
ショップサーブの件も同じで、平文だったかどうかは公表されていません。
参考:イーストア「不正アクセスによる個人情報漏えいに関するお知らせ(第2報)」
保存方式が分からないからこそ、利用者は「パスワードの使い回しをやめる」ことでしか自衛できません。
サービスを作る側が、どう保存しているかを外から確認できないのは、少し怖い話だと思います。
ここまで説明してきた、ハッシュ化や暗号化をする以前の状態もありうる、ということです。
このニュースを読んで感じたこと
パスワードの保存方式は利用者からは見えません。
だからこそ、サービスを作る側が「ちゃんとやっているかどうか」で被害の大きさが変わるんじゃないでしょうか。
ただ、ハッシュ化していれば絶対に安全というわけでもありません。
どのハッシュ関数をどんな設定で使うかによって守れる度合いが大きく変わります。
さいごに
最後に整理します。
- ハッシュ化は戻せない、暗号化は鍵があれば戻せる
- パスワードのように「一致確認だけでいい」ものはハッシュ化で保存する
- 同じパスワードで同じ値にならないようソルトを使う
- 平文保存は盗まれた時点でそのまま悪用される
ハッシュ関数の選び方や設定の重さについては別の記事で詳しく書いています。
SHA-256やMD5のようなよく聞く名前が、実はパスワード保存に向いていない理由もそこで触れます。
少しでも整理の役に立てば幸いです。
最近よく聞くけど今さら聞けない技術用語について、いくつか記事を書いています。
良かったらそちらもご覧ください。