暗号、ハッシュ、メッセージ認証、デジタル署名、証明書の違いをわかりやすく

後で思い出せるように自分用にメモ。

用語

暗号関連を理解する上で、必須の用語。

  • 機密性   ・・・「特定の人しか見られないぜ!」なこと
  • 正真性   ・・・「改ざんされてないぜ!」なこと(完全性とも言う)
  • 認証性   ・・・「確実にAさんから送られてきたものだぜ!」なこと
  • 否認不可能性・・・「それを送ったのは私じゃないよ!」を否定するぅぅぅぅぅう!なこと

暗号関連の技術 → 5つ

暗号関連で使われる技術は、基本は以下の5つ。

  1. 暗号・・・
    • 一定の法則に従ってぐちゃぐちゃにして読めなくすること。
    • その法則に「今回はこういう感じでぐちゃぐちゃにしてね」と言って渡すデータのことを鍵(カギ)と言う。
    • ぐちゃぐちゃにした文章は、鍵を使うと元に戻せる。
    • つまり「鍵」と「法則」さえ分かれば、平文↔暗号文を行き来できる。
  2. ハッシュ・・・
    • 一定の法則に従ってぐちゃぐちゃにして読めなくすること。
    • 暗号と似ているが暗号と違って「一度ぐちゃぐちゃにすると元に戻せない」「出力される文字数は固定」という特徴がある。
  3. メッセージ認証・・・
    • 暗号(共通鍵方式)とハッシュを使って、「確実にあの人から送られてきたものだぜ!」を証明すること。
    • ただし、共通鍵を使っているので、第三者に「確実にあの人から送られてきたものだぜ!」を証明することはできない。なぜなら共通鍵は自分も持っているので「自分の共通鍵を使ったんじゃねーの?」と思われてしまうから。
  4. デジタル署名・・・
    • 暗号(公開鍵方式)とハッシュを使って、「確実にあの人から送られてきたものだぜ!」「もしあの人がそれを拒否したとしても証拠があるもーーーん!!」を証明すること。
    • メッセージ認証と違って、第三者に対しても「確実にあの人から送られてきたものだぜ!」を証明できる。
  5. デジタル証明書・・・
    • デジタル署名で使われる公開鍵に付けられる「この公開鍵は本人のモノだぜ!」を証明するもの。
    • 単に「証明書」と呼ばれることが多い。
    • デジタル署名では、送信者の公開鍵を使って「確実にあの人から送られてきたものだぜ!」を証明するわけだけど、そもそもその公開鍵が偽物だったら意味がない。なので「その公開鍵が送信者のものかどうか?」を証明するのが証明書。
    • 証明書をつけずに、デジタル署名を使うこともできる。

 

表にすると以下のような感じ。

機密性 正真性 認証性 否認不可能性
暗号
ハッシュ
メッセージ認証
認証付き暗号
デジタル署名
(※ただし、検証に使用する公開鍵が偽物だったらになる)
デジタル署名
(+デジタル証明書)

 

これらは組み合わせることもできる。

例えば「メッセージ認証+暗号」「デジタル署名+暗号」みたいにして使うこともできる。

(ちなみに「メッセージ認証+暗号」の組み合わせのことを「認証付き暗号」などと呼んだりする。)

暗号

暗号には

  • 公開鍵暗号
  • 共通鍵暗号

の2種類がある。

暗号についてはそこまでややこしくないので省略。

ハッシュ

ハッシュもそこまでややこしくないので省略。

メッセージ認証

ここらへんからややこしいので詳しく書いていく。

 

まず、AからBに「うんこ」というメッセージを送るとする。

Bからするとビックリである。なぜならAがいきなり「うんこ」と送ってきたからである。

「Aの気が狂ったのか?」「Aは何を伝えたかったのだ?」などなど色々な疑問があるものの、Bからすると

  • 「うんこ」というメッセージは本当にAが書いたものなのか
  • 「うんこ」というメッセージは途中で改ざんされたものではないのか

を確認することができない。

本人に直接会ったり電話をすれば確認できるが、今はできないのだ。

さて困った。

 

はい!!

こんなとき、メッセージ認証を使うとこの2つの問題を解決できます!!

 

以下がメッセージ認証の手順。

メッセージ認証の仕組み(手順)

  1. AとBのどちらかが「共通鍵」をつくる
  2. 共通鍵」を作ったほうがもう一方に渡す
  3. Aがやること:
    1. 共通鍵」と「メッセージ」(うんこ)を同時にハッシュ関数に放り込んで、「ハッシュ値」をゲットする
    2. Bに対して「ハッシュ値」と「メッセージ」の2つ送る
  4. Bがやること:
    1. Aから送られてきた「メッセージ」と、自分が持っている「共通鍵」を同時にハッシュ関数に放り込んで、「ハッシュ値」をゲットする
    2. 送られてきた「ハッシュ値」と、自分でゲットした「ハッシュ値」を比べる。

これでハッシュ値が同じなら確実にAが送ってきたものだと分かるし、改ざんされていないことも分かる。

もし違うなら、Aが送ってきたものではないかもしれないし、改ざんされているのかもしれない。

デジタル署名

まず、AからBに「うんこ」というメッセージを”メッセージ認証”で送るとする。

Bからすると

  • 「うんこ」というメッセージは本当にAが書いたもので
  • 「うんこ」というメッセージは途中で改ざんされていない

というのは分かっている。なぜならお互いに共通鍵を持っているからだ。

ついでに言うと「Aは頭のおかしい奴」というのもBは分かっている。

 

それはさておき、BはCに対して「Aがこんなメッセージを送ってきたんだぜ?あいつ頭おかしいよな」というのを伝えたとする。

するとCはこう答えるのである。

「そのメッセージって本当にAが送ってきたものなのか?Bが自作したものじゃないのか?」

と。

 

Bはこう答える。

「いやいや、これは”メッセージ認証”という仕組みで送られてきたものだから確実にAが送ったきたものだよ」

しかしCはこう答える。

「でもBもAと同じ共通鍵を持ってるんだよな?だったらBが自作自演することもできちゃうよな?」

と。

 

Bは答えることができず黙ってしまった。。。

 

はい!!

こんなとき、デジタル署名という仕組みを使えば、Cに対しても「Aがこんなメッセージを送ってきたんだぜ?あいつ頭おかしいよな」というのを立証することができます!!

 

以下がデジタル署名の手順。

デジタル署名の手順(仕組み)

  1. Aがやること:
    1. 公開鍵」と「プライベート鍵」を作る
    2. 公開鍵」を誰でも見れるように公開する
    3. 「うんこ」というメッセージを「プライベート鍵」を使って暗号化する
    4. 「暗号化したメッセージ」と「メッセージ」(うんこ)をBに送る
  2. Bがやること:
    1. Aの「公開鍵」をゲットする
    2. Aの「公開鍵」を使って、Bから送られてきた「暗号化したメッセージ」を復号化する
    3. 復号化した「メッセージ」と、送られてきた「メッセージ」を比べる

 

これでハッシュ値が同じなら確実にAが送ってきたものだと分かるし、改ざんされていないことも分かる。

そして、Cから「でもBもAと同じ共通鍵を持ってるんだよな?だったらBが自作自演することもできちゃうよな?」と疑われたとしても

Bは「だったらAが公開している公開鍵で送られてきたメッセージをチェックしてみてくれよ」と言い返すことでき、Cがチェックして本当だった場合、Bに対して「悪かった」と謝罪させることができる。

ちなみに、実際のデジタル署名では、以下のようにハッシュ化も行われる。

デジタル署名の手順(仕組み)ハッシュ化もあり

  1. Aがやること:
    1. 公開鍵」と「プライベート鍵」を作る
    2. 公開鍵」を誰でも見れるように公開する
    3. 「うんこ」というメッセージをハッシュ関数に放り込んで、「ハッシュ値」をゲットする
    4. 「ハッシュ値」を「プライベート鍵」を使って暗号化する
    5. 「暗号化したハッシュ」と「メッセージ」(うんこ)をBに送る
  2. Bがやること:
    1. Aの「公開鍵」をゲットする
    2. Aの「公開鍵」を使って、Bから送られてきた「暗号化したハッシュ」を復号化する
    3. 「メッセージ」をハッシュ関数に放り込んで、「ハッシュ値」をゲットする
    4. 復号化した「ハッシュ」と、自分でハッシュ化した「メッセージ」を比べる

ハッシュ化する理由は、高速化のため。

例えば送りたいメッセージが巨大であった場合、送りたいメッセージを直接暗号化してしまうと暗号化するのにも時間がかかるし、暗号文自体も巨大になってしまう。

なので「一旦ハッシュ化したものを暗号化する」という手順を取る。

デジタル署名(+デジタル証明書)

「デジタル署名ですべて解決!」と思いきや、まだ残っている問題がある。

それは「Aが公開している公開鍵がはたして本物かどうか?」という点。

 

もしかしたら、Aが公開している公開鍵はDによってすり替えられているかもしれない。Aは頭が悪いからだ。

そんなとき、Aが公開している公開鍵に「デジタル証明書」というものを付ければ、「これは本当にAの公開鍵だよ!」というのを第三者に証明してもらうことができる。

ここでは、その第三者を「Z」とする。

 

デジタル証明書があると、デジタル署名の手順が以下のように変化する。(ハッシュ化も行っています)

デジタル署名(+デジタル証明書)の仕組み(手順)

  1. Aがやること:
    1. 公開鍵」と「プライベート鍵」を作る
    2. 公開鍵」を「Z」に送りつけ、「Z」に対して「この公開鍵の持ち主を訊いてくるやつがいたらAのものだ!」と言ってくれとお願いする
    3. 公開鍵」を誰でも見れるように公開する
    4. 「うんこ」というメッセージを同時にハッシュ関数に放り込んで、「ハッシュ値」をゲットする
    5. 「ハッシュ値」を「プライベート鍵」を使って暗号化する
    6. 「暗号化したハッシュ」と「メッセージ」(うんこ)をBに送る
  2. Bがやること:
    1. Aの「公開鍵」をゲットする
    2. 公開鍵」を見ると、「この公開鍵はたしかにAのものである。Zが証明する。」という証明書が付いていたので、Zのところに行き「これって本当にAの公開鍵なの?」と確認する。
    3. もしZが「うん本物だよ」と言った場合は、その「公開鍵」を使って、Bから送られてきた「暗号化したハッシュ」を復号化する
    4. 「メッセージ」をハッシュ関数に放り込んで、「ハッシュ値」をゲットする
    5. 復号化した「ハッシュ」と、自分でハッシュ化した「メッセージ」を比べる

 

ただし、ここで更に問題が出てくる。

それは

Zははたして信頼できるやつなのか

という点だ。

AからするとZは信頼できるやつなのかもしれないが、BからするとZは信頼できるやつか分からない。

 

ちなみに、ここでいう「Z」のことを一般的に「認証局」(CA)と呼ぶのだけど

基本的に認証局は以下のような特徴がある。

  • 誰でも認証局になることができる。
    • 個人でも法人でも。
    • 例えばこれを見ているあなたも今すぐに認証局になることができる。(opensshコマンドなどを使えばすぐに証明書を作れる。)
  • その認証局が信頼できるかどうかは自分が決める。
    • そもそも信用とは何か?
  • 認証局は、認証局→認証局→認証局→認証局という感じで、”信頼の輪”というものが出来上がっている。
    • 例えば、ZはYのことを信用するし、YはXのことを信用する・・・・なのでXは信用できるよね!みたいな感じ。
    • でもZのことは信用していいの?
  • 大元の認証局のことを「ルート認証局」と呼ぶ。
    • 例えば「ZはYのことを信用するし、YはXのことを信用する・・・・」という場合、「Zは誰からの信用も得ていないので信用できないのか?」となってしまうので、この場合は国や政府が「Zを保証する」と宣言すると、Zはルート認証局となる。
    • もしくはZが自ら信用を勝ち取って「私はルート認証局だ!」と名乗ったりもできる。

つまり、元をたどっていくと「信用とは何か?」という問題にぶち当たる。

例えば、国から「Zを保証する」とお墨付きをもらっていたとしても、「国が保証しているからと言ってZのことを信用してもいいのか?」となったりもする。

でも大抵の人は「国が保証してるから大丈夫だろう」と判断する。それは国のことを信用しているから。

なので最終的に「認証する存在は信用できるヤツなのか?」を判断するのは自分しかない。

 

 

あと、このように「公開鍵とか認証局とかデジタル署名とか証明書とか色々な仕組みを使って信用を担保する仕組みのこと」をひっくるめて「PKI」(公開鍵基盤)と呼んだりもする。

ちなみにGPGという暗号化ソフトでは、企業などの認証局を頼らずに個人同士の”信頼の輪”だけで信頼を担保する仕組みを採用してたりする。

まとめ

いろいろ書きましたが、暗号関連のことを学びたい場合は、以下の本が超絶オススメです。

 

この記事の内容も、この本の内容を薄めに薄めて書いた内容です。(ちなみに昨日読みました)

読んだ感想も書いてます↓。

参考「暗号技術入門第3版」を読んだ感想

 

 

 

おわり

暗号
スポンサーリンク
この記事を書いた人
penpen

1991生まれ。WEBエンジニア。

技術スタック:TypeScript/Next.js/Express/Docker/AWS

フォローする
フォローする

コメント

タイトルとURLをコピーしました