暗号化通信って難しいという話。
共通鍵暗号
紀元前から存在するとされる古典的な暗号方式。
暗号化と復号化を同じ鍵(共通鍵)で行う。
- 共通鍵の受け渡しの通信自体が盗聴されていたら、その後の通信内容も全部復号化されてしまう
- 共通鍵を安全に送るためには暗号化しなくてはいけないが、その暗号化のための鍵を暗号化するためには・・・(無限ループ)
- N人とそれぞれ暗号化通信するのに$ _N C _2 $個の鍵が必要。 30人なら435個の別々の鍵が必要。
公開鍵暗号
暗号化する鍵と復号化する鍵が別になっている。
復号化するときは暗号化に使った鍵とペアの鍵でないと復号化できない。
公開鍵で暗号化されたデータは、対になる秘密鍵でしか復号化できない。
公開鍵暗号のみを使った通信
- サーバは公開鍵と秘密鍵のペアを作る。
- クライアントは公開鍵と秘密鍵のペアを作る。
- サーバとクライアントでそれぞれの公開鍵を交換する。
- サーバはクライアントの公開鍵で、クライアントはサーバの公開鍵でそれぞれ暗号化して通信する。
- 秘密鍵のやり取りはしない。
- 公開鍵が盗まれても通信内容自体は解読できない
- 公開鍵は公開しても問題ないので、通信相手全員に同じ公開鍵をわたしてもOK
- N人とそれぞれ暗号化通信するのに必要な鍵の数は$ 2N $個なので共通鍵暗号より少ない
- 公開鍵暗号における、暗号化処理と復号化処理は共通鍵暗号に比べてコストが高い!!!
公開鍵と共通鍵を使った暗号化通信
- サーバは公開鍵と秘密鍵のペアを作る。
- クライアントに公開鍵を渡す。
- クライアントは共通鍵を作る。
- 共通鍵を公開鍵で暗号化してサーバに送る。
- サーバは秘密鍵で共通鍵を復号化して入手する。
- 共通鍵をつかって暗号化通信する。
暗号化、復号化のコストが高い公開鍵暗号は、共通鍵の受渡しのためだけに使う。
あとの通信は共通鍵だけなので楽ちん。
共通鍵は通信のセッションが終わったら破棄するので長期管理も不要。
公開鍵暗号による通信の問題点
盗聴者に通信を中継されてしまうと、暗号化しているつもりでも内容がバレてしまう。
- サーバは公開鍵と秘密鍵のペアを作る。
- クライアントに公開鍵を渡す途中で、中継者が公開鍵を入手する。
- 中継者は公開鍵と秘密鍵のペアを作る。
- 中継者はクライアントに、中継者の公開鍵をわたす。
- クライアントは中継者の公開鍵で暗号化して、サーバにデータを送信してしまう。
- 中継者は自分の秘密鍵でデータを復号化して、盗聴する。
- 復号化したデータをサーバの公開鍵で暗号化してサーバに送信する。
- サーバは自分の秘密鍵でデータを復号化する。
上記の手順では、クライアントは公開鍵が偽物だと気づけないし、サーバも自分の秘密鍵で復号化できるので中継者に気づくことができない。
そこで、電子署名
の仕組みが必要になってきます。
電子署名
公開鍵暗号の仕組みを使ってデータの偽装を検知できる仕組み。
送信側はデータのハッシュ値
と秘密鍵
で計算した値を署名
として、データとセットにして送る。
受信側はデータのハッシュ値
と公開鍵
と署名
を使って計算することで、データが送信前と変わっていないことを検証することができる。
基本的には、ハッシュ値を秘密鍵で暗号化したもの(署名)を公開鍵で復号化して、データのハッシュ値と比較することで検証が可能と説明されることが多い。(Wikipediaにも図説が乗っている)
ここで「秘密鍵って復号化する側だったのでは?」と思った人はたぶん正しい。
電子署名≠秘密鍵で暗号化を読んで見てほしい。
証明書
公開鍵に自分の身元情報などを加えたものに、第三者による電子署名を付けたものです。
これを使えば公開鍵が偽装されることがなくなる。やったね。
とはなりません。。。。
電子署名を検証するためには受信側に署名につかわれた秘密鍵と対になる公開鍵(証明書)が必要でした。
しかし、その証明書を検証するためには、署名者の証明書が必要で、さらにその署名者の証明書を検証するために・・・
証明書の検証に終わりがなくなってしまいます。
ルート認証局
ちなみに、公開鍵に電子署名をつけて証明書にする役割をするものを認証局(CA)と呼びます。
じつは、ブラウザ・OSには最初から特定の認証局の公開鍵(証明書)がインストールされており、
証明書の検証ループがインストールされている認証局の署名までたどり着けば、検証作業は終わりを迎えます。
この認証局はルートCAと呼ばれています。
ルートCAの証明書は誰が署名しているのかといえば、ルートCA自身です。
自身の正しさを持って、自身の正しさを証明するというかっこいいヤツです。
あとの説明はめんどくさいので外部に投げます。
http://e-words.jp/w/ルートCA.html
これで、ようやく安心して暗号化通信ができるようになりました。
めでたしめでたし
クライアント認証
証明書よって、クライアントの正当性を証明することで認証とする仕組みです。
- クライアント証明書用に、秘密鍵と公開鍵のペアを作る。
- 認証局にお願いして、公開鍵に署名をつけてもらい、証明書を作る。
- クライアントに証明書と秘密鍵のペアをインストールする。
- サーバにはクライアント証明書に署名した認証局の証明書を設定しておく。
- サーバは認証が必要なアクセスがあると、クライアントに証明書を要求する。
- クライアントが提示した証明書の署名が検証OKであれば、認証局が認めたクライアントで有ることが証明できるので、信頼して認証する。
疑問
私自身、良くわかってないことが1つありまして。
クライアント認証のフローにおいて、クライアントの秘密鍵はなくしてしまっても機能するように思えてしまいます。
おそらく、サーバがクライアント証明書から取り出した公開鍵で共通鍵を暗号化して、クライアントに渡すので、
クライアント側に秘密鍵がないと共通鍵を復号化できない仕組みになっているのではと推測してますが、
わかる人がいたら教えてほしいです。