ITの教科書検索
入門読了 約10分

ハッシュ関数とは ― 改ざん検出とパスワードの保存

ハッシュ関数は、入力を決まった長さの値に変え、元に戻せない技術です。1文字の違いで値がどう変わるか、パスワード保存にソルトが要る理由を図で確かめられます。

目次
  1. ハッシュ関数とは、入力を固定長の値に変える一方向の技術
  2. 性質:一方向性・固定長・衝突困難性
  3. 代表的な方式:SHA-256とMD5・SHA-1が推奨されない理由
  4. 図で確かめる:1文字変えるとハッシュ値はどう変わるか
  5. 改ざん検出への応用
  6. パスワード保存とハッシュ化
  7. ソルト:同じパスワードでも違う値にする
  8. 図で確かめる:ソルトの有無を比べる
  9. 練習問題
  10. 参考にした資料

ハッシュ関数とは、入力を固定長の値に変える一方向の技術

ハッシュ関数は、どんな長さの入力からも決まった長さの値を作る技術です。作った値から元の入力を求めることは、現実的にはできません。ダウンロードページに載っている「SHA-256」の値は、この性質を使っています。Webサービスがパスワードをそのまま保存しない仕組みも同じです。

作った値をハッシュ値、またはメッセージダイジェストと呼びます。暗号化は、鍵を使って元に戻せる形にデータを変換する技術です。ハッシュ関数は、鍵を使わず、元に戻せない形で値を作ります。この性質を生かして、データが途中で変えられていないかの確認や、パスワードの保存に使います。

性質:一方向性・固定長・衝突困難性

FIPS 180-4は、アメリカの国立標準技術研究所(NIST)の規格です。SHA-256などの方式を「反復的な一方向のハッシュ関数」と説明しています。一方向性とは、ハッシュ値から元の入力を、現実的な時間では計算で求められないという性質です。

出力の長さは、入力の長さに関係なく一定です。この性質を固定長と呼びます。たとえばSHA-256は、1文字の入力でも長い文章の入力でも、常に256ビットの値を作ります。

もう1つの性質が衝突困難性です。違う2つの入力から、同じハッシュ値ができることを衝突と呼びます。FIPS 180-4は、意図的に衝突する2つの入力を見つけることも、計算上不可能だとしています。

短い入力(1文字)あ長い入力(文章)ITの教科書の記事SHA-256SHA-256256ビット固定長の値256ビット固定長の値元のデータ?×元に戻せない(一方向性)短い入力(1文字)あ長い入力(文章)ネットワークの教科書の記事SHA-256SHA-256256ビット固定長の値256ビット固定長の値?元のデータ×元に戻せない(一方向性)
1文字の入力と長い文章の入力は、どちらもSHA-256で256ビットの値になります(固定長)。出力から元のデータへ戻る方向には進めません(一方向性)。

FIPS 180-4は、さらにもう1つの性質を挙げています。入力をどこか1か所でも変えると、高い確率でハッシュ値が変わるという性質です。この性質は、後の節の図で確かめられます。

代表的な方式:SHA-256とMD5・SHA-1が推奨されない理由

代表的な方式はSHA-256です。SHA-2というファミリーの一種で、NISTのFIPS 180-4で定められています。CRYPTRECは、日本の暗号評価の取り組みです。SHA-256は、その「電子政府における調達のために参照すべき暗号のリスト」でも、現行暗号リストに載っています。

方式出力の長さCRYPTRECの分類(令和5年3月30日版)
SHA-256(SHA-2)256ビット現行暗号リスト
SHA-384/SHA-512(SHA-2)384/512ビット現行暗号リスト
SHA-1160ビット運用監視暗号リスト(互換性維持のためだけに利用を認める)
MD5128ビット現行・運用監視のどちらのリストにも載っていない

SHA-1とMD5は、新しく作るシステムでは使いません。2017年、GoogleとCWI Instituteの研究チームが発表を行いました。同じSHA-1のハッシュ値を持つ異なる2つのファイルを作ったという内容です。NISTはこの発表を受けて、より強いハッシュ関数への移行の必要性を強調しています。

NISTは、SHA-1を2011年から非推奨とし、2013年末にはデジタル署名での使用を禁止しました。CRYPTRECの分類でも、SHA-1は互換性維持のためだけに利用を認める運用監視暗号リストに入っています。

MD5は、1992年のRFC 1321で定められた、128ビットの値を作る古い方式です。2011年のRFC 6151は、MD5への攻撃が公表されたことを問題にしています。デジタル署名のように衝突困難性が必要な用途では、MD5を使えないとしています。MD5は、CRYPTRECの現行暗号リスト・運用監視暗号リストのどちらにも載っていません。

図で確かめる:1文字変えるとハッシュ値はどう変わるか

「Passw0rd1」と、最後の1文字だけを変えた「Passw0rd2」で、SHA-256のハッシュ値を比べます。macOSやLinuxでは、printf '%s' 'Passw0rd1' | shasum -a 256 で同じ値を確かめられます。末尾に改行を付けて計算すると、値が変わります。

入力文字列
Passw0rd1
アルゴリズム
SHA-256
ハッシュ値(16進数64桁)
963ef1140e817de9c8597680a08c4a70aea11b67cf74a4716a1b05ad9a00d11a

2つのハッシュ値を2進数にして比べると、256ビットのうち121ビットが異なります。1文字変えただけでも、ハッシュ値の半分近いビットが入れ替わります。

改ざん検出への応用

1文字変えるだけでハッシュ値が大きく変わる性質は、データが途中で変えられていないかの確認に使えます。送信者は、本文のハッシュ値を計算して一緒に送ります。受信者は、受け取った本文からハッシュ値を計算し直して比べます。

送信者本文のハッシュ値H1を計算する本文とH1を送る受信者受け取った本文からH2を計算するH1とH2を比べる一致不一致改ざんなしと判断改ざんの疑いあり送信者本文のハッシュ値H1を計算する本文とH1を送る受信者受け取った本文からH2を計算するH1とH2を比べる一致不一致改ざんなしと判断改ざんの疑いあり
送信者は本文とハッシュ値H1を送ります。受信者は受け取った本文からハッシュ値H2を計算し直し、H1と比べます。一致すれば改ざんなしと判断し、一致しなければ改ざんの疑いがあります。ただし、本文とH1の両方を書き換えられると、この比較では気付けません。

2つの値が一致すれば、本文は途中で変わっていないと判断できます。一致しなければ、途中で変わったことが分かります。ただし、本文とハッシュ値の両方を書き換えられると、この比較では気付けません。そのため、ハッシュ値は本文とは別の経路で受け取るか、デジタル署名で守ります。秘密の鍵を混ぜて、書き換えた人が値を作り直せないようにする方法がメッセージ認証符号です。

暗号の基礎の記事で説明したデジタル署名でも、ハッシュ値を使います。RSAやECDSAなどの方式では、本文そのものではなく、このハッシュ値をもとに秘密鍵で署名を作ります。署名を検証する側も、受け取った本文からハッシュ値を計算し直してから、署名を確かめます。

電子証明書とPKIの記事で説明した証明書の署名も、同じ仕組みです。認証局は、証明書の中身から計算したハッシュ値をもとに署名します。

証拠のディスクを複製したときも、原本と複製のハッシュ値を比べて同一性を確かめます。この使い方はデジタルフォレンジックスの記事で説明しています。記録のまとまりごとに前のハッシュ値を持たせ、書き換えを見つける仕組みがブロックチェーンです。

パスワード保存とハッシュ化

Webサービスは、利用者のパスワードをそのまま保存しません。保存するのは、パスワードのハッシュ値です。ログイン時には、入力されたパスワードのハッシュ値を計算して、保存された値と比べます。一方向性があるため、保存されたハッシュ値だけを見ても、元のパスワードは分かりません。データベースが漏えいしても、攻撃者はハッシュ値から直接パスワードを読み取れません。

ただし、ハッシュ値が漏えいすると、パスワードの候補を次々に試す攻撃ができます。候補のハッシュ値を計算し、保存された値と一致するかを確かめる方法です。候補を単語の一覧から選ぶものが辞書攻撃です。すべての組み合わせを試すものが総当たり攻撃です(不正アクセスの記事)。解読されたパスワードは、別のサービスを狙うパスワードリスト攻撃にも使われます。

ソルト:同じパスワードでも違う値にする

ソルトを使わないと、同じパスワードを使う利用者は、保存されるハッシュ値も全員同じになります。攻撃者は、よく使われるパスワードのハッシュ値をあらかじめ計算した対応表を用意できます。表に載っているパスワードなら、比べるだけで、同じ値を持つ利用者全員のパスワードを割り出せます。

ソルトは、ハッシュ化する前のパスワードに付け加える、利用者ごとに違う値です。NISTのSP 800-63B(2025年の第4版)は、パスワードにソルトを付けてハッシュ化することを求めています。ソルトの長さは、32ビット以上にするとしています。

同じパスワードでも、ソルトが違えば保存されるハッシュ値も違う値になります。次の図で、ソルトがある場合と無い場合を比べます。

図で確かめる:ソルトの有無を比べる

次の図は、同じパスワード「Passw0rd1」を使う利用者A・Bの例です。ソルトなしとソルトありを切り替えると、保存されるハッシュ値の違いを比べられます。仕組みを見やすくするため、この例はパスワードの後ろにソルトを付けて、SHA-256を1回かけただけの値です。ソルトも短くしています。

利用者Aのパスワード
Passw0rd1
保存されるハッシュ値
963ef1140e817de9c8597680a08c4a70aea11b67cf74a4716a1b05ad9a00d11a
利用者Bのパスワード
Passw0rd1
保存されるハッシュ値
963ef1140e817de9c8597680a08c4a70aea11b67cf74a4716a1b05ad9a00d11a

2人とも同じパスワードを使っているので、保存されるハッシュ値も同じになります。攻撃者は、よく使われるパスワードのハッシュ値を計算した対応表(レインボーテーブルなど)と比べるだけで、同じ値を持つ利用者全員のパスワードを割り出せます。

実際のパスワード保存では、SHA-256を1回かけるだけでは足りません。SP 800-63Bは、パスワード用のハッシュ方式を使うよう求めています。この方式は、パスワードとソルトに加えて、計算の手間を決める値(コスト)を入力にとります。NISTが認める方式の例は、SP 800-132で定めるPBKDF2です。これは、パスワードから鍵を作る鍵導出関数の1つです。

PBKDF2は、ハッシュ化の処理を決めた回数だけ繰り返して、1回の計算に時間をかけます。この工夫をストレッチングと呼びます。SP 800-63Bは、コストを性能が許す範囲でできるだけ高くするよう求めています。計算機の性能向上に合わせて、引き上げることも求めています。1回の計算が重いほど、攻撃者が候補を試す速度は遅くなります。

練習問題(全5問)

Q1ハッシュ関数の一方向性として正しい説明はどれ?
Q2SHA-256が作るハッシュ値の長さとして正しいものは?
Q3入力文字列の最後の1文字だけを変えたとき、SHA-256のハッシュ値はどうなるか?
Q4SHA-1について、確かめられている事実として正しいものは?
Q5同じパスワードを使う利用者が複数いても、保存するハッシュ値を利用者ごとに違う値にするための工夫は?

選んでから「採点する」を押すと、解説つきで答え合わせができます。

参考にした資料

関連記事

おすすめの本 PR

セキュリティとデータベースは、基本情報技術者試験の対策本でまとめて学べます。

目的別の本の選び方を見る

セキュリティの記事を続けて読む

セキュリティ 全37本中16本目