情報ラボ > ハッシュと電子署名
届いたデータは、途中で書きかえられていないか。送ってきたのは、本当にその人か。データの「指紋」を計算して確かめるしくみを、ブラウザの中で実際に動かして体験しましょう。
「abc」の値は ba7816bf… で始まり、NIST が公開している SHA-256 の計算例と同じになります。入力が0文字でも1000文字でも、ハッシュ値はいつも256ビット(16進数1けた=4ビットなので64けた)です。16進数は2進数・16進数、UTF-8 は文字コードで確かめられます。
ある4けたの数字(暗証番号を想定)のハッシュ値です。元の数字は何でしょう。
選んだファイルは、この端末のブラウザの中だけで計算し、どこにも送信しません。大きなファイルは時間がかかることがあります。
ソフトウェアの配布元は、ファイルとは別に、公式のWebページにハッシュ値を載せていることがあります。ファイルとハッシュ値を同じ道から受け取ると、両方まとめてすり替えられるおそれがありますが、信頼できる別の道で受け取ったハッシュ値と比べれば、すり替えに気づけます。ただし、その「信頼できる道」そのものが本物かどうかは、ハッシュ値だけでは確かめられません。そこで使われるのが、次の電子署名です。
パリティビットやチェックディジット(パリティマジック)も、まちがいを見つけるしくみです。ただし、こちらは通信や入力のうっかりしたまちがいを見つけるためのもので、わざと書きかえる相手は想定していません。
このタブでは、ブラウザの Web Crypto API を使い、ECDSA(楕円曲線を使う電子署名、曲線は P-256、ハッシュは SHA-256)で、本物の鍵ペアを作って署名と検証をしています。
●●●●●●●●(Aさんだけが持つ。画面には出しません)
●●●●●●●●(Bさんだけが持つ)
同じ文でも、もう一度署名すると署名の値が変わります。ECDSA は署名のたびに新しい秘密の乱数を使うからです。それでも、検証はきちんと成功します。
Bさんが「これがAさんの公開鍵です」とうそをついて自分の公開鍵を配ったら、Bさんの署名がAさんの署名として通ってしまいます。そこで、信頼できる認証局が「この公開鍵はAさんのもの」という内容に電子署名をした電子証明書を使います。受け手は、OSやブラウザに組みこまれた認証局の公開鍵で、証明書を検証します。
https のWebページでも、サーバはサーバ証明書を送り、ブラウザが認証局の電子署名を確かめてから暗号化した通信を始めます。流れはWebページが表示されるまでで確かめられます。
本物のパスワードは入力しないでください。user01 と user02 は、わざと同じパスワードにしてあります。
攻撃者は、よく使われそうなパスワードのハッシュ値を前もって計算した表を持っているとします。
スマートフォンのアプリとサービス(サーバ)が同じ共有鍵を持ち、それぞれが「今の時刻」と鍵から同じ計算をします。ここでは共有鍵に、RFC 6238 の試験用の値 12345678901234567890 を例として使っています。
ハッシュ関数は、どんな長さのデータからも、決まった長さの値を計算する関数です。計算された値をハッシュ値(メッセージダイジェスト)といいます。ハッシュ値は、データの「指紋」のようなものです。ファイルが1バイトでもちがえば、ハッシュ値はまったくちがうものになるので、2つのデータが同じかどうかを、短い値を比べるだけで確かめられます。暗号のしくみでも少しふれましたが、このページでは、そのしくみと使い道をくわしく見ていきます。
セキュリティに使うハッシュ関数(暗号学的ハッシュ関数)には、次の性質が求められます。
アメリカ国立標準技術研究所(NIST)の規格 FIPS 180-4 は、安全なハッシュ関数の条件として、「あるハッシュ値になるメッセージを見つけること」と「同じハッシュ値になる2つのちがうメッセージを見つけること」が計算上困難であることを挙げています。前者が一方向性、後者が衝突困難性にあたります。
入力はいくらでも長くできるのに、出力は256ビットに決まっています。入力の種類のほうがはるかに多いので、同じハッシュ値になる入力の組(衝突)は、必ずどこかに存在します。大切なのは「存在しない」ことではなく、「見つける方法がない」ことです。SHA-256 のハッシュ値は 2256 通り(約 1.16×1077 通り)もあるので、でたらめに探して同じ値を見つけることは、現実には不可能です。
「ハッシュ値を作る」タブの3つめの実験のように、元のデータの候補が少なければ、候補を全部ハッシュ値にして比べることで、元のデータを見つけられてしまいます。4けたの数字なら1万通りなので、一瞬です。これはハッシュ関数の弱点ではなく、元のデータの種類が少なすぎることが原因です。短いパスワードをハッシュ値にして保存しても安全とはいえない理由は、ここにあります(パスワードの強さ)。
SHA-256 は、NIST が FIPS 180-4「Secure Hash Standard」で定めているハッシュ関数の1つで、SHA-2 とよばれるグループに属します。264 ビット未満の長さのメッセージから、256ビットのハッシュ値を計算します。256ビットは16進数で64けたなので、上のツールでは64文字の値が表示されます。
計算では、まずメッセージの後ろに、決まった規則で「1のビット」と「0のビット」とメッセージの長さを付け足して、長さを512ビットの倍数にそろえます。そして512ビットずつのブロックに区切り、ブロックごとに、ビットの回転やシフト、排他的論理和(XOR)、足し算などを64回くり返して、中身を細かくかき混ぜていきます。前のブロックの結果が次のブロックの計算に入るので、どこか1ビットでも変わると、その影響が最後の値まで広がります。これが雪崩効果の正体です。XOR などの演算は、論理回路で確かめられます。
日本では、デジタル庁・総務省・経済産業省が「CRYPTREC暗号リスト」をまとめていて、政府の情報システムで使う暗号を選ぶときの基準にしています。SHA-256 は、その電子政府推奨暗号リストに載っています。
ハッシュ関数も、研究が進むと弱点が見つかることがあります。MD5 は128ビットのハッシュ値を作る関数ですが、衝突を短い時間で作る方法が次々に見つかり、2011年に公開された RFC 6151 では「電子署名のように衝突困難性が必要な用途には、もはや使えない」とされました。
SHA-1(160ビット)についても、2017年2月に Google とオランダの研究機関 CWI が、同じ SHA-1 のハッシュ値になる、内容のちがう2つのPDFファイルを実際に作って公表しました。NIST は2022年12月、SHA-1 を使っている人はできるだけ早く SHA-2 か SHA-3 に移るようすすめ、NIST の規格の中で SHA-1 を使うのを2030年12月31日までに終える計画を発表しています。CRYPTREC暗号リストでも、SHA-1 は「互換性を保つため以外の目的では使うことをすすめない」運用監視暗号リストに入っています。安全とされていた方式も、時間がたつと見直されるのです。
ハッシュ値は「データの指紋」なので、データが書きかえられていないか(完全性)を確かめるのに使えます。送り手はデータとハッシュ値をいっしょに送り、受け手は受け取ったデータからハッシュ値を計算し直して比べます。一致すれば途中で変わっていない、一致しなければ書きかえられたか、こわれたと判断できます。
ソフトウェアの配布元が、ファイルのハッシュ値を公開していることがあります。たとえば Linux の一種である Ubuntu は、配布するファイルの SHA-256 のハッシュ値の一覧(SHA256SUMS というファイル)を公開しています。ダウンロードしたファイルのハッシュ値を計算して公開された値と比べれば、途中でこわれたり書きかえられたりしていないかが分かります。Windows では、PowerShell の Get-FileHash というコマンドで、ファイルの SHA-256 を計算できます。このページの「ハッシュ値を作る」タブでも、ブラウザの中だけで計算できます。
ただし、ハッシュ関数には鍵がなく、だれでも同じ計算ができます。攻撃者がデータを書きかえ、そのハッシュ値も計算し直してつけかえれば、受け手には見分けがつきません(「改ざんを見つける」タブの3つめの場合)。そこで、ハッシュ値はデータとは別の、信頼できる道で手に入れる必要があります。Ubuntu がハッシュ値の一覧とあわせて、その一覧に電子署名をつけたファイル(SHA256SUMS.gpg)を公開しているのは、一覧そのものが本物であることを確かめられるようにするためです。
パリティビットやチェックディジット(パリティマジック)も、データのまちがいを見つけるしくみです。これらは、通信や入力のときの「うっかり」のまちがいを見つけるためのもので、わざと書きかえる相手は想定していません。たとえばパリティは、2か所のビットを同時に反転させると見のがしてしまいます。暗号学的ハッシュ関数は、悪意のある相手がいても、同じハッシュ値のまま中身を書きかえることが現実的にできないように作られている点がちがいます。
すり替えを防ぐには、「その人にしか作れないしるし」が必要です。それが電子署名で、公開鍵暗号のしくみを応用しています。公開鍵暗号では、対になる秘密鍵と公開鍵を使います。電子署名では、送り手が自分の秘密鍵で署名を作り、受け手は送り手の公開鍵でその署名を検証します。秘密鍵は本人しか持っていないので、検証に成功すれば、本人が作ったこと(本人性)と、署名のあと内容が変わっていないこと(完全性)の両方を確かめられます。
実際には、長いデータそのものではなく、そのハッシュ値に対して署名します。公開鍵暗号の計算は時間がかかりますが、データがどれだけ大きくても、ハッシュ値なら256ビットで済むからです。ここで衝突困難性が重要になります。もし同じハッシュ値になる別のデータを作れたら、署名をそのまま別のデータに付けかえられてしまいます。MD5 や SHA-1 が電子署名に使えなくなったのは、このためです。
このページの「電子署名」タブでは、ブラウザに組みこまれた Web Crypto API を使い、ECDSA(楕円曲線を使う電子署名の方式、曲線は P-256)で、実際に鍵ペアを作って署名と検証をしています。ECDSA は NIST の電子署名の規格 FIPS 186-5 で定められている方式の1つで、CRYPTREC暗号リストの電子政府推奨暗号リストにも載っています。ECDSA では署名のたびに新しい秘密の乱数を使うため、同じ文に署名しても、署名の値は毎回変わります。
総務省の「国民のためのサイバーセキュリティサイト」の用語集では、電子署名によって、なりすましやメッセージの改ざんが行われていないことの検証と、否認防止ができると説明しています。否認防止とは、送った人が、あとから「自分は送っていない」と言い逃れできないようにすることです。
日本では「電子署名及び認証業務に関する法律」(電子署名法、平成12年法律第102号)が、電子署名を「その情報を作った人が行ったものであることを示す」ことと、「その情報が改変されていないかを確認できる」ことの2つを満たす措置と定めています。また第3条では、本人だけが行うことができる電子署名がされた電子データは、「真正に成立したもの」、つまり本人によって作られたものと推定すると定めています。紙の書類の印鑑や手書きのサインに近い役割を、法律の上でも持たせているのです。
電子署名には、もう1つ問題が残っています。受け手が持っている「Aさんの公開鍵」は、本当にAさんのものでしょうか。もしBさんが「これがAさんの公開鍵です」と言って自分の公開鍵を配っていたら、Bさんの署名がAさんの署名として通ってしまいます。
そこで、信頼できる第三者である認証局(CA)が、「この公開鍵はこの人(このサーバ)のものです」という内容に電子署名をして、電子証明書を発行します。受け手は、認証局の公開鍵で電子証明書の署名を検証してから、その中に書かれた公開鍵を使います。証明書の中身を1文字でも書きかえれば、認証局の署名の検証に失敗するので、証明書の偽造は見抜けます。総務省の用語集では、認証局を「電子証明書の登録、発行および失効などを行う第三者認証機関」と説明しています。このように、認証局と電子証明書で公開鍵の持ち主を保証するしくみ全体を、公開鍵基盤(PKI)といいます。インターネットで使われる電子証明書の形式は、RFC 5280 で定められています。
では、認証局の公開鍵はどうやって信頼するのでしょうか。パソコンやスマートフォンのOSには、信頼できる認証局の証明書(ルート証明書)があらかじめ組みこまれています。たとえば Apple は、iPhone や Mac にあらかじめ入っているルート証明書の一覧を公開しています。認証局が別の認証局やサーバに証明書を出し、それをさらにたどっていくと、最後はこのルート証明書に行きつきます。こうして、信頼が鎖のようにつながっていきます。
https のWebページを開くと、サーバはブラウザにサーバ証明書を送ります。ブラウザは認証局の電子署名を検証して、通信相手が本物のサーバかどうかを確かめてから、暗号化した通信を始めます。この流れは、Webページが表示されるまでの「表示までの流れ」で、TLS の手順として確かめられます。
ログインのとき、サービスは、入力されたパスワードが正しいかを確かめます。そのためにパスワードをそのまま保存していると、データが流出したときに、全員のパスワードがそのまま知られてしまいます。パスワードの強さで見たように、使い回しがあれば、ほかのサービスまで危険になります。
そこで、パスワードそのものではなく、ハッシュ値を保存します。ログインのときは、入力されたパスワードのハッシュ値を計算して、保存してある値と比べればよいのです。一方向性があるので、保存された値から計算でパスワードを求めることはできません。
ただし、ハッシュ値だけで保存すると、弱点が2つあります。1つは、同じパスワードの人は同じハッシュ値になるので、流出したデータを見るだけで「この2人は同じパスワード」と分かってしまうことです。もう1つは、よく使われるパスワードのハッシュ値を前もって計算した表を用意しておけば、表と見比べるだけでパスワードが分かってしまうことです。
これを防ぐのがソルト(salt、塩)です。ソルトは利用者ごとに作るランダムな値で、パスワードにソルトを加えてからハッシュ値を計算し、ソルトとハッシュ値の両方を保存します。同じパスワードでもソルトがちがえばハッシュ値は別の値になり、前もって作った表も使えなくなります。攻撃者は、利用者1人ずつ、そのソルトを使って候補を計算し直さなければなりません。NIST のデジタル認証の指針 SP 800-63B-4(2025年)は、パスワードをソルト付きでハッシュして保存すること、ソルトを32ビット以上の長さにすることを求めています。このページでは128ビットのソルトを使っています。
SHA-256 は速く計算できるように作られているので、攻撃者も1秒間にたくさんの候補を試せます。そこで、パスワードの保存には、計算を何回もくり返して、わざと時間がかかるようにした方式を使います。SP 800-63B-4 は、パスワードとソルトに加えて、計算の手間を決める値(コスト)を入力にとる「パスワードハッシュ方式」を使うよう求めています。このページの4つめの保存方法では、その1つである PBKDF2(NIST SP 800-132 で定められている方式)を、10万回くり返す設定で計算しています。正しい利用者にとっては一瞬の待ち時間でも、何億もの候補を試したい攻撃者にとっては、大きな負担になります。
認証とは、相手が本人かどうかを確かめることです。総務省の「国民のためのサイバーセキュリティサイト」では、認証に使う要素を次の3つに分けています。
| 要素 | 内容 | 例 |
|---|---|---|
| 知識情報 | 本人だけが知っていること | パスワード、暗証番号 |
| 所持情報 | 本人だけが持っているもの | スマートフォン、ICカード |
| 生体情報 | 本人の体の特徴 | 指紋、顔、静脈、虹彩 |
このうち2つ以上を組み合わせて認証するのが多要素認証で、2つを使う場合を二要素認証といいます。パスワードが漏れても、攻撃者が利用者のスマートフォンを持っていなければログインできません。IPA(情報処理推進機構)も、不正ログイン対策として、長く複雑なパスワードを使い回さないことに加えて、多要素認証の設定をすすめています。
なお、認証を2回に分けて行うことを二段階認証といいます。パスワードと秘密の質問のように、同じ「知識情報」を2回使うものは、二段階ではあっても二要素ではありません。総務省の用語集でも、同じ要素を2回使うより、異なる要素を2回使うほうがセキュリティのレベルは高くなると説明しています。
TOTP(Time-Based One-Time Password、RFC 6238)は、時刻をもとに、短い時間だけ使えるパスワード(ワンタイムパスワード)を作る方式です。利用を始めるとき、サービスとアプリの間で同じ秘密の鍵を共有します。RFC 6238 は、この鍵を利用者ごとに別のものにし、ランダムに作ることを求めています。そのあとは、アプリとサービスの両方が、次の計算をします。
同じ鍵を持ち、時計が合っていれば、アプリとサービスは同じ数字を計算できます。数字は30秒ごとに変わるので、一度盗み見られても、しばらくすると使えなくなります。30秒という長さは、RFC 6238 が、安全性と使いやすさのバランスからすすめている値です。また RFC 6238 は、通信にかかる時間を考えて、1つ前の30秒の数字まで受け付けるくらいにとどめるようすすめています。上のツールのサーバも、この考え方で、今の数字と1つ前の数字を受け付けています。
ワンタイムパスワードも万能ではありません。偽のログイン画面(フィッシングサイト)に数字を入力してしまうと、攻撃者がその数字を、有効なうちに本物のサイトで使えてしまいます。NIST の SP 800-63B-4 も、ワンタイムパスワードによる認証はフィッシングへの耐性がない、としています。あやしいメールやサイトの見分け方はあやしいメールを見分けるで、端末の中の秘密鍵を使い、パスワードを相手に渡さずに本人確認をするパスキーについてはパスワードの強さで確かめましょう。パスキーも、このページの電子署名と同じく、秘密鍵と公開鍵の組を使うしくみです。
このページの計算は、すべてブラウザの中で行い、入力した文字やファイルはどこにも送信しません。
情報Ⅰ 授業の進め方ガイドでは、この教材を次の授業で使います。ねらい・導入の問い・50分の流れ・確認問題をまとめています。