忙しい現代人の腰&肩のお悩み対策!

デジタル署名の仕組みについて教えてください。

デジタル署名の仕組みは、メールの内容(原文)からメッセージダイジェストを作成し、それを送信者の秘密鍵で暗号化したものを署名として原文(または暗号文)に付けるということですが、どうして単に原文そのものを暗号化したものを署名として送らないのでしょうか?

改ざん防止の為であれば、原文そのものを暗号化して送れば、受信側で改めてメッセージダイジェストを作成し、それと復号化したメッセージダイジェストを突き合わせて検証するようなことをしなくても済むと思うのですが。

いづれにしても公開鍵で復号化できるということは、秘密鍵を持っている送信者が署名した段階から改ざんされていないはずですし、その公開鍵が証明書等により検証できていれば、確かに本人であるということになりますよね。

現実世界の「署名」のように、署名とは原文とは別につけるもの(=わざわざ復号化しなくても原文が読める)、いうことに似せているだけのことでしょうか?

(参考URL)
http://www.ipa.go.jp/security/awareness/administ …

このQ&Aに関連する最新のQ&A

A 回答 (5件)

No.4です。

回答のお礼欄を拝見する限りご理解いただけたようですが、若干補足いたします。

回答のお礼欄に
『そう簡単に「悪意のある第三者が勝手に(m',s')を公開してしまえば...」ということはできないのでしょうが…』
とありますが、ご質問にあるメッセージ復元型の電子署名の場合で、もしm'が意味のある数字である必要がないのであれば、公開されている検証鍵と公開情報だけあれば簡単に偽造できてしまいます。というのも、現在使われている公開鍵暗号系を用いた電子署名は数値演算によって構成されており、先の回答でも書いたとおり適当な数字s'に対して、公開されている署名鍵(e,n)を使ってs'^e mod nは誰でも演算ができます。この演算結果をm'と言ってしまえば、結果的にs'はm'の署名になっているわけです。

これに対しハッシュ関数(h=Hash(m))を用いた署名の場合ですが、
署名:s=h^d mod n
検証:h=s^e mod n ⇒ if h==Hash(m) then True else False
となります。
このとき、先ほどと同様に適当な数字s'に対してはs'^e mod nは計算できますが、その後の判定を成功させるにはs'^e mod nとなるようなHash(m')を作る必要があります。しかし、ハッシュ関数が暗号学的な一方向性のものであれば、当然ハッシュ関数の逆演算はできないため、Hash(m')==s'^e mod nとなるようなm'を求めることは事実上不可能です。

一般的には
「あるメッセージに対して、署名鍵を知らない人でも署名が作れる」
ということだけを偽造と考えると思いますが、暗号学の世界では
「ある署名の値に対して、署名鍵を知らない人でもこの署名に合うようなメッセージを作れる」
という偽造に対しても安全性を担保する必要があり、そのためにハッシュ関数が使われているとなります。

もし暗号・署名の仕組みや安全性とかに興味があれば、参考URLにあるような大学の学部生向けの暗号の教科書とかもありますので、ぜひ読んでみてください。

参考URL:http://book.akahoshitakuya.com/b/4526064521
    • good
    • 0
この回答へのお礼

もし原文そのものを署名とした場合は、たとえ(偽造した署名による)検証結果=原文が意味を成さないものであれ、それ以上の検証ができないことから、「公開鍵で検証した結果なのだから本来の署名者が確かに署名したものだ!」と主張できてしまうということですね。

そして、検証結果は公開鍵により簡単に偽造できるということですね。

それならば単に原文そのものを署名とすることには問題がありますね。メッセージダイジェストによる検証が必要であると納得できます。

どこでも説明されているデジタル署名の仕組みについて素朴な疑問だったのですが、深いというか根本的なことが関わっていたのですね。

ありがとうございました。

お礼日時:2012/11/28 07:07

これより先に回答した方が指摘されていないことですが、単に原文そのものを暗号化したものを署名として送るのでは、署名の偽造ができてしまう(存在的偽造が可能である)からです。



RSA署名で考えて見ます。署名(秘密)鍵を(d,n)、検証(公開)鍵を(e,n)とします。

メッセージダイジェスト(ハッシュ関数)を使わない場合、メッセージmに対する署名は
署名:s=m^d mod n
となり、このsを公開します。検証者はこのsと検証鍵を使って
検証:m=s^e mod n ※s^e mod n=(m^d)^e mod n=m^ed mod n=m
を計算することで検証となります。

このとき、悪意のある第三者がある適当な乱数s'を用意し、
m'=s'^e mod n
を用意し、勝手に(m',s')を公開してしまえば、署名者が署名処理をしていない(s'=m'^d mod nを計算していない)にも関わらず署名者の署名ができてしまい、偽造が成功しています。

もちろん、このときのmが意味のあるメッセージになっていない可能性の方が非常に高いですが、それでも「この意味も無いメッセージに署名していない」ことは保証できません。これが「存在的偽造が可能」ということです。

メッセージダイジェストを使う理由としては、計算コスト云々よりも、このような偽造を防ぐ目的の方が(少なくとも学術的には)意味として強いです。
    • good
    • 0
この回答へのお礼

デジタル署名には「存在的偽造が可能」があるのですか!

RSA暗号では、「秘密鍵を用いずに暗号文から平文を得ることは難しい」という安全根拠があり、改ざんについては実用面ではほぼ不可能なのでしょうが、なりすましに関しては可能ということでしょうか?

まあ、そう簡単に「悪意のある第三者が勝手に(m',s')を公開してしまえば...」ということはできないのでしょうが(そう簡単であれば利用されないでしょうから)、「秘密鍵を用いずに暗号文から平文を得ること」よりは簡単にできるという程度のものなのでしょうか。

その脆弱性を補うために、受信側でも原文からメッセージダイジェストを別途作成して検証するわけですね。

ネットで調べる内容では、とてもここまでのことは説明されていないので、大変勉強になりました。

ありがとうございました。

お礼日時:2012/11/27 17:24

ざくっと言えば、容量と計算時間が無駄ですし、頑張ってその方式でやっても実用されるような平文に対して暗号化されたデータが署名の意味を持たないからでしょうね。

ちょっと頑張ってその方式でやる方法を考えてみますが、公開鍵暗号で平文全体を暗号化する方法も、分割する方法もうまくいきません。前者は現実的な計算時間ではできませんし、後者は改ざんに対して脆弱です。

公開鍵暗号で暗号化できるデータの最大サイズは、例えば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のデータをつけていたのとは明らかに必要な容量が減っています。

つまり、メッセージダイジェストを使った方が明らかに送信するデータは少なくなっていて、同じ効果が得られます。それだけでもメッセージダイジェストを暗号化した方が良いと言えるでしょう。


というわけで、あえて電子署名を使わないという方法を考えると非常に効率が悪いか、脆弱性があるかのどちらかの方法しかないので電子署名を使っているんだと思います。
    • good
    • 0
この回答へのお礼

やはり、本文を公開鍵暗号方式でまるごと暗号化してしまうと、(平文のデータ量次第で)処理に負荷がかかってしまい、実用的ではないのですね。

「公開鍵暗号で暗号化できるデータの最大サイズ」というものがあるのですね。どんなデータも同じく暗号化できるものだと思っていました。それならば、本文は暗号化に使用できないというのに納得がいきます。それで一定長のメッセージダイジェストを利用するのですね。大変勉強になりました。

ありがとうございました。

お礼日時:2012/11/27 16:49

あ、そうそう。

その大前提として「公開鍵による復号化処理は
メチャメチャ重い」ってコトもあります。

全文を暗号化すると、復号に手間がかかって仕方ありません。
ですので、ハッシュ値を暗号化することで、復号処理を軽量化
してるんです。

同じように、VPN通信でも「共通鍵を公開鍵で送り、本文は
共通鍵で暗号化」なんて面倒なことをしますよね。これも
「公開鍵による復号化はメチャメチャ手間がかかる」ためで、
共通鍵を送る程度なら何とかなる・・・ってのが前提にあります。
    • good
    • 0
この回答へのお礼

なるほど、復号化処理の負荷が無駄に大きくなってしまうのですね。
ありがとうございました。

お礼日時:2012/11/27 16:36

一番大きな理由は、「暗号化したい文書では無いから」です。



デジタル署名付きの文書は、文書そのものを誰にでも公開
したいんですね。ですので、本文は暗号化できない。

でも、暗号化せず本文を公開すると、文書を改ざんされても
判断が付かないんです。「誰にでも見てほしい」「でも本文は
改ざんされたくない」という時に使うのが「デジタル署名」なん
ですね。

デジタル署名が正しく復号出来るなら、その文書は改ざん
されていない、復号できないなら怪しい・・・ってことですから
「リアル」での「サイン」と意味は全く同じです。

内容も秘密にしたい場合は、デジタル署名と暗号化を同時に
する・・・なんてこともしますよ。

この回答への補足

「誰にでも見てほしい」「でも本文は改ざんされたくない」だとしても、本文を暗号化したものを復号化してもらえばよいのでは? と思いました。デジタル署名としても復号化するわけですから。

補足日時:2012/11/27 16:30
    • good
    • 0

このQ&Aに関連する人気のQ&A

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!

このQ&Aを見た人が検索しているワード

このQ&Aと関連する良く見られている質問

Q昨今の迷惑メールの目的は何!?

迷惑メール減ったな~と思った時期もつかの間、
1週間くらい前から、今までにないぐらいのペースで送りつけられてきています。。

メールアドレスの変更や指定受信は都合上できないので、
キャリア固有の迷惑メール対策をしています。
※未承諾広告メール拒否(真面目に未承諾広告を謳う業者もいないでしょうが・・)
※なりすましメール拒否(サーバ側で本当に判定できてるのか?)
※大量送信者メール拒否(これが機能しているとしたらスポットで送られてきてるのか?)
※ドメイン指定拒否も、重複なく、羅列文字列ドメインではない頻繁に来るドメインを登録して、
枠の120ドメイン使い切ってしまっています。

真夜中でも数分に1通きて本当に一睡もできません。
サイレントにして就寝すると朝起きたときには未読メールが200弱。
(睡眠時間が長いわけではありません、4時間くらい。)

携帯を家に忘れて出かけると、帰った時には受信BOXがいっぱいで
大事なメールも押し出されているといった事もありました。

最初の迷惑メールでアドレスの存在が業者に知られると、
業者間を通じて多数の業者に出回るという理屈もわかりますが、
この尋常でない量の迷惑メールが始まった時期、突然の量、送信元アドレス、時間帯、内容を見ると
今自分の所に送られてきているメールの送信元業者はそれほど多数ではなく
一部の業者が同一の対象に大量に送りつけてきているように思っています。

これを書いている最中の今も、1分に1通のペースで送られてきていますが、
昔と違ってこの迷惑メールの真意がわからなく思っています。
当初は金銭目的の為に、数千万の宛先に誘い文句を送れば
そのうち数十万のアドレスがヒットして、そのうち数人は騙されるだろう
的なことだったのは間違いないと思います。

でも今わたしの携帯には、同じ送信元アドレスから、同内容で、上記の頻度で送られてきています。
「騙す」といった意味合いでの迷惑メールではなく、まさに「迷惑」メールになっています。
文面に誘われるどころか、ノイローゼにでもなってしまいそうなほどに。
パケット定額にしてるからよかったものの、携帯に疎い人やweb閲覧に興味ない人など
定額制にしてない人だったら通信料もバカにならないでしょうし。

業者としてもある程度の効果を期待して送信作業をしているとは思えません。
コンピュータからの自動送信と思いますが、
送信元アドレス、送信先、内容、等の振り分けや、
頻度の調整をインプットするのも簡単なことだと思うのですが
それらを「意図的」に設定せず、寧ろ「意図的」に上のように送りつけてきて、
騙す為のメールではなく精神的な嫌がらせのように感じます。

気が狂いそうです。
(このPCも発狂しそうな心を汲み取ってくれたかのように
「きがくるいそう」でいくら変換しても「器楽羸痩」しか出てこなかった。)
この迷惑メール、どーーなんでしょう???

迷惑メール減ったな~と思った時期もつかの間、
1週間くらい前から、今までにないぐらいのペースで送りつけられてきています。。

メールアドレスの変更や指定受信は都合上できないので、
キャリア固有の迷惑メール対策をしています。
※未承諾広告メール拒否(真面目に未承諾広告を謳う業者もいないでしょうが・・)
※なりすましメール拒否(サーバ側で本当に判定できてるのか?)
※大量送信者メール拒否(これが機能しているとしたらスポットで送られてきてるのか?)
※ドメイン指定拒否も、重複なく、羅列文字...続きを読む

Aベストアンサー

迷惑メール業者=宣伝したい会社、ではないこともあります。

宣伝したい会社→(内容&お金)→メール送信業者→(メール配信)→ユーザー

メール送信業者は、例えば「一日10万通の配信実績があります!」とうたい文句にし、広告出稿の営業をします。

それならば、と広告配信を依頼する会社も出てくるでしょう。

しかし実際は、その10万通も99.99%以上がただ捨てられるだけ。

それでもメール配信業者は、「確かに配信いたしました!」と言って、そのメールにどれだけ反応があろうが無かろうが、もうお金はもらっているので感知しないのです。

そんなバカな配信業者がいくつもあり、そんなのに出稿してしまう会社も無くなることなく…(多分、配信数に対して費用が安いため。)

だから、迷惑メールからは逃げるしかないでしょう。
私などは、迷惑メールが1通届いたらすぐにアドレスを変えてしまいます。
現在、迷惑メールフィルタはかけていませんが、1年以上迷惑メールは届いていません。

----

なお、挙げられていた迷惑メール拒否機能はほとんど意味がありません。理由を書きます。

>※未承諾広告メール拒否(真面目に未承諾広告を謳う業者もいないでしょうが・・)
これで出している業者はほぼゼロでしょうね。

>※なりすましメール拒否(サーバ側で本当に判定できてるのか?)
『携帯アドレスを騙ったPCメール』は、拒否できています。しかし一般インターネット上のドメインで、他ドメインから鳴りすましを受けたようなものは、判定できません。

>※大量送信者メール拒否(これが機能しているとしたらスポットで送られてきてるのか?)
これは、『ケータイから』大量送信を繰り返す人からのメールを拒否します。インターネット上から来るメールは、それが何通出されたか知る手段はなく、拒否できません。
メール中毒のユーザーでもない限り、ケータイ(手動)で一日に何百通も打つことはしないでしょう。

>※ドメイン指定拒否も、重複なく、羅列文字列ドメインではない頻繁に来るドメインを登録して、
ドメイン指定拒否機能自体、ほとんど意味がありません。From: のアドレスは実際に存在しないアドレス・ドメインであってもチェックされておらず、いくらでも嘘アドレスを書いて出せるからです。
しかし、どうしても欲しいというユーザーの声のため、追加されました。(以前は「指定ドメイン受信」機能だけでした。それで必要十分なのに…。)
まあサイトに誘導するには、実アドレスである必要がありますが、毎月いくつものドメインを取って、いくつかメールを出したら使い捨てているので、1年前の迷惑メールのドメインはほぼ消えていることでしょう。

◎有効な迷惑メール対策は、「PCからのメールを全て拒否する」もしくは、「指定ドメイン(アドレス)受信」だけです。
本当に必要なPCメールがいくつあるのか、数えてみてはいかがでしょう?

迷惑メール業者=宣伝したい会社、ではないこともあります。

宣伝したい会社→(内容&お金)→メール送信業者→(メール配信)→ユーザー

メール送信業者は、例えば「一日10万通の配信実績があります!」とうたい文句にし、広告出稿の営業をします。

それならば、と広告配信を依頼する会社も出てくるでしょう。

しかし実際は、その10万通も99.99%以上がただ捨てられるだけ。

それでもメール配信業者は、「確かに配信いたしました!」と言って、そのメールにどれだけ反応があろうが無かろうが、もうお金はもらっているの...続きを読む

Qintとlongは同じ?

#include <stdio.h>
#include <limits.h>

int main() {
printf("%d\n%d", INT_MAX, LONG_MAX);
return 0;
}

出力
214783647
214783647

Win7 64bit (VC++2010)
CentOS 32bit (gcc)

どちらの環境でも同じ出力結果となりました。
intとlongなぜ同じになってしまったのでしょうか。

Aベストアンサー

long は 32ビットの整数(signedの場合 -2147483648~+2147483647、unsignedの場合
0~4294967295)
int は システムにおける 標準
という定義です。

32ビットシステムの場合は同じになります。

DOS時代はシステムが 16ビットのため、intは -32768~+32767(または 0~65535)でした。

short int とすることで 16ビット互換となります。

QCString から LPCTSTRの型に変換

visual studio 2013 VC++を使用していますが、WINDOWSの関数に渡すためにCString からLPCTSTRに変換する必要があります。実際にどのようにするのかわかりません。
例えば、以下のサンプルは他の質問コーナーの回答をアレンジしたものです

CString str = _T("ABC");
int siz = str.GetLength()+1;
LPCTSTR pszFName = new TCHAR[siz];
_tcscpy_s( pszFName, siz, str );

で変換するのですが
LPCTSTRからwchar_t*へ変換できませんとエラーがでます
_tcscpy_s()は使用できないのでしょうか

Aベストアンサー

>APIはCStdioFile の Open()でファイル名を与えるところ

APIではないようですが……。

http://msdn.microsoft.com/ja-jp/library/ee247566.aspx
ならば、そのままCStringの変数渡せば、よろしく処理してくれると思いますけど。

Qジョブとタスクの違いは?

基本情報処理試験の勉強をしてるのですが、ジョブとタスクの違いがわかりません。
どなたか教えていただけないでしょうか?

よろしくお願いします。

Aベストアンサー

最初に出くわす、疑問です。
懐かしい言葉です。
皆さん、悩む事項の一つです。

Job Task 日本語に訳すと「仕事」です。
ジョブは、一般的に、コンピュータシステムの外部から認識される仕事の単位で、
コンパイル、リンク、実行はよく使われるジョブを構成するジョブステップと言われる例です。

それとは対照的な、タスクは、コンピュータの中での細分化された仕事の単位です。
これは、コンパイルするためにはコンピュータの中でどんな仕事に切り分けられるかです。
これは、コンピュータの中で発生する仕事の単位です。
例えば、ソースイメージをファイルから「読み込む」という仕事、それを何回かで読み込む仕事、読み込んだソースを分析し、機械語に書き直す仕事、機械語に書き直したファイルを「書き出す」仕事、こういったことをコンピュータの中ではやっている訳です。
こうしてタスクを管理するのは、タスクコントローラと言います。
ジョブを管理するのをジョブコントローラと言い、情報処理では、完全に分離されます。

タスクコントローラに関しては、この後だんだんと理論が深くなっていきます。
CPUを使う仕事と、ファイルを読み書きする仕事といったことです。
タスクスケジューラ、I/O完了待ち合わせ、ディスパッチャー、同期管理といった理論に入っていきます。
特にもう一つぶち当たる「壁」は、プログラム作成における「ルーチン」です。
「リエントラント型」、「リユーザブル型」です。
日本語的には、「再入可能」、「再利用可能」というものです。
特にタスクと関係するのは、ディスパッチャの「リエントラント型」のタスクコントローラといった理論は、最高に面白くなると思います。

応援してます。
がんばって。

最初に出くわす、疑問です。
懐かしい言葉です。
皆さん、悩む事項の一つです。

Job Task 日本語に訳すと「仕事」です。
ジョブは、一般的に、コンピュータシステムの外部から認識される仕事の単位で、
コンパイル、リンク、実行はよく使われるジョブを構成するジョブステップと言われる例です。

それとは対照的な、タスクは、コンピュータの中での細分化された仕事の単位です。
これは、コンパイルするためにはコンピュータの中でどんな仕事に切り分けられるかです。
これは、コンピュータの中で発生する仕事の...続きを読む


人気Q&Aランキング