質問: メールのデジタル署名は、なぜ本文を暗号化しないの? デジタル署名の仕組みについて教えてください。 デジタル署名の仕組みは、メールの内容(原文)からメッセージダイジェストを作成し、それを送信者の秘密鍵で暗号化したものを署名として原文(または暗号文)に付けるということですが、どうして単に原文そのものを暗号化したものを署名として送らないのでしょうか? 改ざん防止の為であれば、原文そのものを暗号化して送れば、受信側で改めてメッセージダイジェストを作成し、それと復号化したメッセージダイジェストを突き合わせて検証するようなことをしなくても済むと思うのですが。 いづれにしても公開鍵で復号化できるということは、秘密鍵を持っている送信者が署名した段階から改ざんされていないはずですし、その公開鍵が証明書等により検証できていれば、確かに本人であるということになりますよね。 現実世界の「署名」のように、署名とは原文とは別につけるもの(=わざわざ復号化しなくても原文が読める)、いうことに似せているだけのことでしょうか? (参考url) http://www.ipa.go.jp/security/awareness/administrator/remote/capter6/7.html
回答: ざくっと言えば、容量と計算時間が無駄ですし、頑張ってその方式でやっても実用されるような平文に対して暗号化されたデータが署名の意味を持たないからでしょうね。ちょっと頑張ってその方式でやる方法を考えてみますが、公開鍵暗号で平文全体を暗号化する方法も、分割する方法もうまくいきません。前者は現実的な計算時間ではできませんし、後者は改ざんに対して脆弱です。 公開鍵暗号で暗号化できるデータの最大サイズは、例えばrsaだと鍵の長さ (素数p, qの積) までです。大きなデータを暗号化するにはそれだけ長い鍵が必要になります。例えば、1mbのデータを暗号化するには8,388,608bit以上の鍵が必要となりますが、これから送るデータがどれくらいのサイズになるのかはわからないので、これから送るかもしれないだけの異常に長い鍵を用意する必要があります。また、公開鍵暗号の場合、誰かがその鍵が正しいことを保証しないと無意味ですが、その裏付けのために長い鍵が必要になります。認証局の公開鍵は信頼出来る公開鍵としてブラウザなどに予め組み込まれるようになっていますが、こんな世界だと認証局は何ビットの公開鍵を配ったら良いのでしょうか。 http://ja.wikipedia.org/wiki/rsa%e6%9a%97%e5%8f%b7 また、公開鍵には計算時間についても欠点があります。一般に使われているコンピュータが一度に計算できるデータの大きさは公開鍵暗号の計算に必要な大きさに比べてずっと小さいです。これを実現するためにソフトウェアで計算をする必要がありますが、それにはそれなりに時間がかかります。また、公開鍵暗号としてよく使われるrsaは掛け算をeやdの回数繰り返すので、さらに時間がかかります。卑近な例で例えると、1桁同士の掛け算がハードウェアで出来る計算でそれ以上の桁数の計算がソフトウェアで計算するところだと考えるとわかりやすいかもしれません。掛け算するときは1桁の計算は九九などで暗記しているので一発ででますが、それ以上の計算は一桁ずつやって足し合わせますよね。rsa暗号での処理もそんな処理をしているので桁数が増えれば必然的に時間がかかるようになります。 というわけで、平文を公開鍵暗号で一発で暗号化するのは現実的ではありません。それでは、分割する方法はどうでしょうか? データを例えば2048bitずつに分割すると、長いデータでも楽に暗号化できますが、この場合は改ざんに弱いという問題が出てきます。暗号文を攻撃する方法としてよくある方法に、暗号文の順序を入れ替えるという方法があります。分割する場合はこれに対処できる必要がありますが、平文と暗号文とを対応させて順番を入れ替えると改ざんされたことを見つけることは不可能です。 そもそも電子署名を使わずに暗号化したデータを署名付きデータと思って送る場合も同じです。暗号化したデータを送り、メッセージダイジェストがない場合、順序の入れ替えがないことを示すのは不可能です。 これに対抗するために、通し番号を振る方法を考えると、効率と安全性のトレードオフになるのであまりやりたくないと思います。効率を考えて8bitの通し番号にすると256ブロック単位での入れ替えには脆弱ですし、64bitの通し番号をつけると8バイトはデータではないものを毎回送ることになるので無駄が多いですしね。 と、ここまでの問題はすべて平文と同じ長さの暗号文を送ろうとしたから起きた問題です。これが平文のメッセージダイジェストを送るようにしていたらどう変るでしょうか。 メッセージダイジェストの値は普通128bitから512bitくらいなので、1024bitの鍵を使ったrsaで一発で暗号化でき、分割の必要はありません。また、通常は鍵長より短いデータはpaddingされますが、rsaで暗号化された後のデータも鍵長より長くならないので、1024bit程度でしょう。これは、1mbのデータを送るのに1mbのデータをつけていたのとは明らかに必要な容量が減っています。 つまり、メッセージダイジェストを使った方が明らかに送信するデータは少なくなっていて、同じ効果が得られます。それだけでもメッセージダイジェストを暗号化した方が良いと言えるでしょう。 というわけで、あえて電子署名を使わないという方法を考えると非常に効率が悪いか、脆弱性があるかのどちらかの方法しかないので電子署名を使っているんだと思います。