Coding - Crypto - Data Security - Digital Signature - PHP - Software

電子署名(構成要素の概要)

 2020年9月4日に法務省・総務省・経済産業省の連名で「電子署名法(ハンコではなくても電子的署名で商法上の契約成立とみなす)」の公告がありました。

電子署名法の概要について: http://www.moj.go.jp/MINJI/minji32-1.html

 しかし、電子署名関連の理解が日本人一般に足りていないようなので、電子署名とは何かを言葉で説明し、実際にPHPで実装する際の知識をエンジニアリングの知識を交えながらまとめます。

 電子署名とはデジタルな情報に対してデジタルに「間違いなく特定の人物が特定の情報について確認したと表明する手法」です。従って「①特定の人物の表明」であることの保証と、「②特定の情報に対して」であることの保証が同時に担保されなくてはなりません。さらに、この保証された状態を「③誰でも確認できる」仕組みでなくてはなりません。

 これら①②③を同時に充足するため、電子署名では「公開鍵暗号」「要約関数(ハッシュ関数ともいう)」という数学的な手法が用いられます。電子署名を理解するのがややこしく感じるのは、電子署名の前にこれらの「公開鍵暗号」「要約関数」についての理解を要するからかと思います。

1. 「電子署名」「電子サイン」「電子契約」

 暗号化や電子署名そのものに触れる前に、昨今の「ハンコ廃止」にからめて「電子署名」「電子サイン」「電子契約」の3つの違いを確認します。

 「電子署名」は「その電子データに改竄がないことを裏付けるための判断データ」、「電子サイン」は「紙ドキュメントにペンで名前を書いて同意を示すように、電子的に名前を書くこと」、「電気契約」は「紙ベースではなく電子的に契約種類が存在することで締結される契約であり、必然的にハンコは押されていない」です。

 加えて「ハンコ」「印章」「印影」「印鑑」の違いも述べると、「ハンコ」は物理的な物体であり「印章」と同じ物です。「印影」は一般的な視点で「紙の上に押されてついた印章の跡」、「印鑑」は「印影のうち銀行や役所のようなところに登録されて証明として使われている物」です。

2. 公開鍵暗号

公開鍵暗号の話の前にもっとシンプルな暗号の話をします。最もシンプルな暗号は「メッセージを暗号にするルールと、暗号をメッセージに戻す(復号という)ルールが同一な暗号」でしょう。これは暗号化と復号化に共通の「鍵」を使う状態なので「共通鍵暗号」と呼ばれます。例えば、アルファベットのメッセージを暗号化するとき、2つ後ろのアルファベットに置き換えるという暗号化(シーザー暗号と呼ばれる方式)の場合は下記のようになります。

元のメッセージ: This is a pen.
暗号化したもの: Vjku ku c rgp.

この方式の弱点は、暗号化の方式(アルファベット2つ後ろ)が他人に知られると、その他人にも暗号を容易に解読されてしまう点です。しかし、暗号の送信者に暗号化してもらうためには暗号化のルール(すなわち暗号解読のルールでもある)を伝えなくてはならない。第二次大戦中にドイツ軍が作ったエニグマは、この暗号化と復号化のアルゴリズムが毎日変わりしかも非常に複雑であったので連合軍は解読に非常に苦労しましたが、結局は共通鍵暗号であったためイギリス軍に協力したアラン・チューリング達によって解読されました。

このような経緯を経て、「暗号化するためのルールと、複合化するためのルールを分けることはできないか?」という要望が出てきました。これを充足したのが「公開鍵暗号」です。わかりやすい例として公開鍵暗号のひとつである「RSA暗号」を簡易化した例で説明すると、

巨大な素数:P
巨大な素数:Q
PとQの積:N
メッセージ:M

を考えたとき、Mを暗号化する際の暗号化ルールとしてPとQの積であるNを必要とする一対一の関数Fenc(N, M)を、暗号化されたMの復号化ルールとして独立したPとQを必要とするFdec(Menc, P, Q)を考えます。このようなFencとFdecを考えられた場合(実際に考えられたのがRSA考案者の賢いところ)、Nを暗号化専用の鍵(公開鍵)として公開し暗号を生成してもらっても、NとFencの値を見た人が復号を行うにはPとQをNから得なくてはならないです。しかし、巨大な数であるNを素因数分解するには膨大な計算資源が必要となるため、その作業をするのは現実的ではありません。なお、暗号の復号を行う「秘密鍵」にはPとQが独立して保存されているため素因数分解をせずにPとQを使って復号化をできます。

ちなみに、あまり言及されないが上記の特性から「秘密鍵があれば公開鍵を生成」できるのに対し、公開鍵からは秘密鍵は生成できません。そして、「秘密鍵」「公開鍵」という表現をそのまま使って良いか議論があるところですがわかりやすさ優先でいうと「秘密鍵で暗号された暗号は公開鍵で復号できる」という不思議な特性があります。この公開鍵暗号RSAの双方向性とも言えるような特性を使って「電子署名」が実現されています。

3. 要約関数

要約関数というのは

・入力が少しだけ変わったからと言って出力が少しだけ変わるのではなく全然違う値が出力される
・特定の出力を得るための入力を特定することが非常に困難
・同じ入力に対しては同じ値が出力される

という不思議な特性を持った関数(数式)です。ちなみに要約関数には上で述べた公開鍵暗号は使いません。この要約関数の性質を用いて、メッセージの内容を入力した場合、メッセージの要約(英語ではダイジェストという)が出力された状態と考えます。

メッセージそのものではなく要約関数を使ってダイジェストを生成するのは、長いメッセージであってもそのダイジェストは非常にコンパクトな値になり、改竄の有無を判断する際の計算資源が節約できて便利なためです。

そこで、メッセージの内容の証明としてこのダイジェストを追加で記載して「このメッセージの要約はこれです!」と相手に送った場合、メッセージが改竄されていないことを示せるでしょうか?答えはNOです。メッセージを改竄し、改竄したメッセージを要約関数に通してそのダイジェストに置き換えてしまえば改竄ができてしまいます。そこで電子署名の出番です。

4. 電子署名

電子署名は単純にいうと「送るメッセージのダイジェストなどを秘密鍵で暗号化したもの」です。メッセージの中には暗号化されていないダイジェストも記載しておき、まずは送られてきた署名を公開鍵で復号化して「絶対に正しい」ダイジェストを得てこれらを比べます。メッセージの中に暗号化されていないダイジェストが記載されてなければ要約関数で得れば良いです。そして、送られてきたメッセージのダイジェストを署名の中に暗号化されて入っていたダイジェストと比較して同じかどうかでメッセージに改竄が無いことを確かめます。この「内容の改竄が無いことを担保する」のが電子署名の目的です。

意地悪な見方として「それではメッセージだけでなく署名も改竄すれば良いのでは?」と思うかもしれません。そのためには「秘密鍵を盗んで署名を作り直す」か「別の秘密鍵で署名を作り直すか」の選択が考えられますが、現実的なのは後者かと思います。この場合、公開鍵も変わってくるので公開鍵が正しいものであるかが重要であり、署名付きの暗号化メッセージとは別に絶対に改竄が発生しない方法で公開鍵を受信者が得られることが重要です。このために、予め直接USBなどや信頼が担保できる方法(キーサーバーに登録)で広く公開鍵を公開・配布することが大事です。

代表的なキーサーバーとしてMITやOpenPGPが運用しているサーバーがあります。公開鍵暗号のためのキーペアを生成したらキーサーバーに登録して公開鍵のすり替えがわかるように公開しておきましょう。

こうして、電子署名は「公開鍵暗号」「要約関数」があって初めて実現します。


次回は電子署名のコーディングの観点からの実装方法に言及します。

Subscribe
Notify of
guest
0 Comments
Inline Feedbacks
View all comments