ikepyonのだめ人間日記

セキュリティに関することを書いていく予定。

SSLというか証明書の誤解?

どうも証明書とかSSLとかについて誤解があるようだ。
私自身よくわかってはいないのだけど、自分の理解の範疇で書いてみる。間違いはあると思うのでツッコミ希望
SSL周りの誤解として、以下のものが挙げられると思う。

  1. 証明書なんて飾りです
  2. SSLで暗号化さえしていれば安全
  3. 自己証明書で問題ないです
  4. ドメイン名と証明書のCNが異なっていても問題ありません
  5. 注意のメッセージが出ますが、無視してください

まあ、これらは全てSSL=通信の暗号化という誤った理解によることが大きいのだけど・・・

暗号って

まず、暗号というのはどうして使うのか考えてみよう。
暗号と言うのは、伝えたい相手にのみ、情報を渡すというために存在すると言ってもいいと思う。この「伝えたい相手のみ」というのが重要となる。暗号を使用する際には、暗号文を複合化復号する方法をあらかじめ「伝えたい相手」に知らせておかなければならない。で、この複合化復号方法を「伝えたい相手」以外が知らないということにより、仮に情報をそれ以外の相手に盗まれても、情報は使用できないと言うことになっている。
そこで、どうやって「伝えたい相手」に「暗号文の複合化復号方法」を共有するかが問題となってくる。「伝えたい相手」が既に知人の場合、直接会って共有することが出来るだろう(これがまあ共通鍵暗号と同じ考え方だと思う)。しかし、「伝えたい相手」を知らない場合、「暗号文の複合化復号方法」を伝える相手が「伝えたい相手」であるとどうやって確認するのかが重要となってくる。
いくら情報を暗号化していても、間違った相手に「暗号文の複合化復号方法」を伝えてしまった場合、その情報は「伝えたい相手」以外に知られてしまう。
したがって、暗号を使うというためには、正しい「伝えたい相手」と「暗号文の複合化復号方法」の共有をおこなっているかということを必ず確認する必要がある。単に、何らかの方法で情報を暗号化すればいいと言うわけではない。

SSLでは通信開始時に「暗号文の複合化復号方法」(要するに暗号鍵)をサーバから受け取って、それを使って暗号化している。この暗号鍵は、通信相手のサーバと自分しか知らないために、暗号化された情報を他人が見ても何が送られているかはわからないようになっている。
先に述べたように、暗号通信を行う際には、確かに正しいサーバから送られてきた暗号鍵であるということを確認する必要がある。この確認がなされないと、ネットワークでは全く別のサーバと通信を行うことになりかねない。ネットワークでは通信相手のサーバと直接パケットを受け渡しするわけではなく、幾つかの機器を経由してデータをやり取りするため、全く別のサーバが暗号鍵を作成し、送りつけることが可能だからだ。IPアドレスFQDNは偽造可能であるので、これらが正しいからと言って、パケットの送信元が正しいものであるとは限らない。
この通信相手が正しいことを確認する方法をSSLではPKIと言う仕組みで実装している。PKIと言うのは言ってみれば信頼の連鎖を作ることで、正しい通信先であるということを確認する方法と考えてもいいと思う。

信頼とは?

例えば、あるコミュニティで私が、21さん本人を知らない人火さんに対して「私があの21ですw」と自己紹介したとしよう。そのときに私のメールアドレスと私のPGP鍵を教えておくw
当然、火さんは、私を21さんだと思い込んで、メールで話をするだろう。そして、もしかしたら他人に知られたくない話をPGPで暗号化してメールで知らせてくるかもしれない。私は聞いた情報を今度は火さんに成りすまして21さんにその内容を伝えたとする。そうすると21さんはその知識があるので、直接会わない限り、火さんとBlogのコメントなど他の方法でやり取りしても、火さんは違和感を感じないだろう。
その結果、火さんが21さん以外に知られたくなかったことが、私にも筒抜けになっている。これは、火さんが自称21さんの私が言ったことを信頼してしまったためである。
これが、オレオレ証明書(自己証明書)の最大の問題点である。通信を暗号化しているつもりが、全く別のサーバと通信をしており、通信内容が漏れてしまっている。暗号化が暗号の意味を成さなくなっているのである。

では、どうすれば相手が21さん本人であると火さんは確認できるのか?
21さんはハンドル名なので、自動車免許などの公的証明書は意味を成さない。
そこで、火さんはお友達のお茶さんを連れてくるw。お茶さんは21さんと知り合いであるとする。火さんはお茶さんに「21さんって誰?」と確認すれば、自称21さんでない21さん本人を教えてくれる。お茶さんが嘘をつかないと火さんが信頼するのであれば、お茶さんに紹介してもらった21さんは本人であるということが信頼できる。仮に、お茶さんが21さん本人を知らなくても、お茶さんが信頼する別の誰かを連れてきてその人に確認をとってもいい。
つまり、自分自身は知らないけど、信頼できる知っている人に確認を依頼することで本人かどうかを確認できるわけである。
これが超いい加減なPKIの仕組みの肝である。PKIでは認証局を信頼し、認証局が発行した証明書を確認することで、相手が正しいことを確認することが出来る。認証局が証明書の発行先を確認する(確認内容は認証局のポリシーに依存する)ことで、発行先が確かに発行先であるということを保障している。
IEなどのブラウザでは、インストール時に信頼できる認証局の大本の証明書(ルート証明書と呼ばれる)を登録している。この証明書が信頼できるとしている認証局によって発行された証明書を持つ認証局は信頼できるという信頼の連鎖を形作っている。

ところが、その信頼の連鎖上にある認証局がいい加減で誰に対しても任意の証明書を発行していると、その認証局が発行した証明書(問題のある認証局の下にある認証局が発行した認証局)は信頼できなくなる。
先の例で言えば、お茶さんが信頼するイノさんが常にうそをつくとする。そのイノさんが、私のことを21さんだと言ったとしたら、間違った認識が火さんに出来てしまう。別の例では、イノさんが50%の確率で嘘をつくとする。この場合、イノさんが言うことは信頼できないので、イノさんに確認することは50%しか信頼できないと言うことになる。
このように認証局が発行する証明書の信頼性と言うのは、認証局の信頼性以上になることはない。

オレオレ証明書が信頼できないのは、自分で自分の本人性を証明することは不可能であることによるものだし、いい加減な認証局によりPKIの仕組み(SSLの仕組み)が壊されるのも認証局の信頼性に依存するからである。
証明書が信頼できない限り、通信の相手先が全く意図しない相手になっている可能性が否定できないため、いくら通信を暗号化しても無意味なのである。

通信を暗号化しさえすればいいというのは、相手が確かに「伝えたい相手」であることがわかってはじめていえることである。
したがって、オレオレ証明書によるSSLは暗号化していないのとそれほど変わらないと言えるんだけどなぁ。

例に出てくる名前はフィクションで実在の人物、組織とは一切かかわりがありませんw

(追記)
よくメールで、「Zipで暗号化してます。鍵は後ほどメールで送ります」というのがあるけど、これってほとんど暗号化している意味はないから。せいぜいmailゲートウェイでウィルスチェックをすり抜けられるぐらいの意味しかないと思っておいたほうが良い。
せめて「電話でおしらせします」ぐらいにはしとかないと。
でも、結構安全だと誤解している人が多いんだよねぇorz