公開鍵暗号方式における「暗号化と復号」と「署名と検証」の違い

# ※お断り
私は暗号学の専門家でも何でもない、最近基本情報技術者を取った一般人です。
試験勉強中に以下のような解説を見ました。
- 公開鍵で暗号化したデータは、秘密鍵でしか復号できない
- 秘密鍵で**暗号化**したデータは、公開鍵でしか**復号**できない
- 署名とは、証明書のハッシュ値を、秘密鍵で**暗号化**したもの

ただ一方、以下の主張もあると知りました。
- 「署名」＝「秘密鍵で暗号化したデータ」という表現はおかしい。
- というか『**秘密鍵で暗号化**』という言い回しそのものがおかしい

実際、私も「なぜ"署名"と呼ぶのだろう？"暗号化"でいいのでは？」と混乱しました。
似たような解説記事は数多く存在しますが、どの記事もいまいち理解できませんでした。
勉強を継続する中で、最近ようやく腑に落ちたので、整理とメモのために記事にします。

https://qiita.com/angel_p_57/items/d7ffb9ec13b4dde3357d

# 要約
### 一番言いたいこと
- 「ある手続きに従ってデータを別の状態に言い換えること」を**暗号化**と言うのは早とちり

### そもそも暗号化/復号/署名/検証って？
- 「暗号化」は、「"特定の情報を持つ人"にしか理解できないようにデータを言い換えること」であって、「言い換えられたデータ(＝暗号)を、"理解できる状態（＝暗号化される前の状態）"に戻す行為」を「復号」と呼ぶ
- 「"特定の情報を持つ人"にしか実行できない行為」を「署名」というし、「その行為が、確かに"その情報を持つ人"によって実行されたことを確かめること」を「検証」という

### 公開鍵暗号方式ってなんだったっけ？
- 「公開鍵暗号方式」とは、「"ある片方の鍵"で言い換えたデータは、"(その鍵の対となる)もう片方の鍵"でしか元に戻せず」、かつ「ある片方の鍵から、もう片方の鍵の情報を得ることは簡単だが、その逆は非常に困難である」という２つの性質を利用した、情報交換の手続きである。
- 「公開鍵暗号方式」における「２つの鍵」とは、（片方の鍵からもう片方の情報を得ることは簡単だがその逆は困難であるという特徴を踏まえて）「公開鍵」と「秘密鍵」と名付けられており、その名の通り「公開鍵」は誰に公開してもよく、「秘密鍵」は特定の誰かだけが持っている必要がある。
- この２つの鍵を使って、データを言い換えたり、元に戻したりできるわけだが、データの変換においては「公開鍵で言い換えて-秘密鍵で元に戻す」と「秘密鍵で言い換えて-公開鍵で元に戻す」という２つの組み合わせが考えられる。

### 公開鍵暗号方式での操作と暗号化/復号/署名/検証の対応関係
- 「公開鍵」と「秘密鍵」がそれぞれ「誰でも持っていていいもの」と「その人本人しか持っていないもの」という特徴を踏まえると以下の通りと言える
    - 公開鍵で言い換えて秘密鍵で元に戻す行為は、暗号化と復号という行為そのもの
    - 秘密鍵で言い換えて公開鍵で元に戻す行為は、署名と検証という行為そのもの

以下、解説します。

# そもそも「公開鍵暗号方式」とは？
## 一般的な解説
一般的には、以下のように解説されています。
> [公開鍵暗号 - wikipedia](https://ja.wikipedia.org/wiki/%E5%85%AC%E9%96%8B%E9%8D%B5%E6%9A%97%E5%8F%B7)
公開鍵暗号（こうかいかぎあんごう、英語: Public-key cryptography）とは、暗号化と復号とに異なる鍵（手順）を用い、暗号化用の鍵は公開できるようにした暗号方式である（復号用の鍵は秘匿）。

> [公開鍵暗号とは何ですか？ - IPA](https://www.ipa.go.jp/archive/security/crypto/qa.html)
公開鍵暗号方式では暗号化する鍵と復号する鍵が異なっているのが大きな特徴です。この方式は一方の鍵を公開しても、もう一方の鍵が計算できないという画期的なものです。


## 私なりの解釈
上述した通りですが、「公開鍵暗号方式」とは、以下の３つの要素を兼ね備えた仕組みだと理解しています。

1. 対となる鍵を使ってデータを **別の状態に"言い換え"** たり、**"元に戻したり"** する仕組み
1.  **一方の鍵で言い換えられたデータ** は、対となる**もう一方の鍵でしか元に戻せない** 仕組み
1.  **ある片方の鍵** から **もう片方の鍵** を作ることは容易だが、**その逆は面倒** な仕組み

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/507249/02e97f72-4fba-964c-1095-8f866e0e7057.png)

## 「公開鍵」と「秘密鍵」とは？

公開鍵暗号では、対となる２つの情報（鍵）を使うと解説されていましたが、
この２つの鍵はその性質から、 **『公開鍵』** と **『秘密鍵』** と呼びます。
初めて聞く人にとっては、とても特徴的で独特な言い回し方だと感じる人も多いでしょう。
しかしこの言い回しは、その特徴を的確に捉えた上手い表現方法だと言えると思います。

公開鍵暗号に対する「私なりの理解」で書いた通り、私は以下のように理解しました。
>**ある片方の鍵** から **もう片方の鍵** を作成することは容易だが、**その逆は非常に困難** な仕組み

この仕組みを理解を補助するために頻繁に使われる例え話に、素因数分解が挙げられます。
※"理解を補助するための例"であって、実際にこの仕組みが使われているとは限りません

>ある大きな数字Ｎが、２つの素数Ｐ，Ｑの積だとした場合に（Ｎ＝Ｐ×Ｑ）、ＰとＱからＮを計算することは簡単ですが、ＮからＰとＱを得ることは一筋縄ではいきません。



# 「暗号化/復号」と「署名/検証」とは？

公開鍵暗号について復習したところで、本題である以下の言葉の意味の理解を進めます。

## 「暗号化/復号」とは？

> [暗号とは - IT用語辞典e-Words](https://e-words.jp/w/%E6%9A%97%E5%8F%B7.html)
暗号とは、ある情報を特定の決まった人しか読めないように一定の手順に基づいて無意味な文字や符号の列に置き換えたもの。情報の伝送や記録、保存の際、第三者に盗み見られたり改竄されないようにするために作成される。

つまり、「暗号化」とは、 **特定の法則と情報を知るもの以外には理解できないように隠すこと** であり、「復号」は **暗号化されたデータを特定の法則に基づいて元に戻すこと** だとわかります。

何度も繰り返すようですが、「**"特定の誰かにしかわからないようなデータ（＝暗号）"に言い換えること** 」を「 **暗号化** 」と呼ぶのであって、「 **単に所定の手続きによってデータを言い換える作業** 」とか、「 **ぱっと見なんかよくわからない文字列に言い換える** 」というだけで「暗号化」と呼ぶには、早とちりだとわかります。


## 「署名/検証」とは？

次に、署名と検証の話をします。さっそくですが、私は以下のように理解しています。

- 「署名」とは、「 **その人以外が代替したり真似したりすることができない行為によって得られた証** 」のことであり、「署名する」とは「 **署名を作成する行為またはその証を添付する行為** 」を指す
- 「検証」とは、「 **得られた証（＝署名）が、その人以外によって代替されたり真似されたりしていないことを確認すること** 」を指す

※ちなみに、「署名」を理解するための補助として、よく「押印」が例に挙げられ、「署名」とはすなわち「印影そのもの」であり、「署名する」とはすなわち「押印すること」だと例えられていると思います。本質は「そのハンコは本人しか持っていない」という点と、「本人しか持っていないはずのものを使って何某かの行為を実施する」という点が共通だということだと思っています。
※ちなみにさらにいえば、そのハンコが確かに、その人しか持っていない唯一無二のハンコであることを証明するために、役所で印鑑登録したり、印鑑証明書を発行してもらったりすると思いますが、今回は証明書の話ではないので省略します。

# 「公開鍵暗号方式」と「暗号化/復号」および「署名/検証」の関係について

## 公開鍵暗号方式で登場する４つの操作

ようやく本題です。
「私なりの理解」では、以下のようにも言いました。

>  **一方の鍵で"言い換えられたデータ"** は、対となる**もう一方の鍵でしか"元に戻せない"** 

この言い回しを、それぞれ「公開鍵」と「秘密鍵」で言い換えれば、以下のようになります
>  **「公開鍵」で言い換えられた** データは、 **「秘密鍵」でしか元に戻せない**
>  **「秘密鍵」で言い換えられた** データは、 **「公開鍵」でしか元に戻せない**

つまり、公開鍵暗号方式では、以下の４つの操作が登場することになります。

>1. "あるデータ"を **「公開鍵」で言い換える** 
>1. "「公開鍵」で言い換えられたデータ"を **「秘密鍵」で元に戻す**
>1. "あるデータ"を **「秘密鍵」で言い換える**
>1. "「秘密鍵」で言い換えられたデータ"を **「公開鍵」で元に戻す**

## 「暗号化/復号」および「署名/検証」との対応関係

改めて、上述の4操作と、「暗号化」「復号」「署名」「検証」の対応関係を考えます。
ここで、「公開鍵」とは誰もが知っている情報で、「秘密鍵」とはその本人しか知らない情報であることを、いま一度しっかりと思い出しておきます。

### 暗号化と復号
>"あるデータ"を「公開鍵」で言い換える＝「秘密鍵」を持っている人にしか元の状態に戻せない状態にする（＝暗号化）

"あるデータ"を「公開鍵」で言い換えた場合、そのデータは「言い換える前の元データを持っている送信者本人」か、「言い換えたあとのデータを元に戻せる受信者（＝秘密鍵を持っている人）」しか知り得ません。
つまり、"あるデータ"を第三者以外には理解できない状態に言い換えるのですから、まさしく「暗号化」の行為そのものと言えるでしょう。
当然、「暗号化」されたデータをもとの状態に戻すことは、「復号」の行為そのものですので、「公開鍵によって言い換えられたデータを秘密鍵で元の状態に戻すこと」は「復号」と言えます。

### 署名と検証

> 送信者から、"送信者が作成した証明書(A)"と、"証明書(A)を元に送信者が自分で計算したハッシュ(B)を、送信者しか持ちえない鍵(=秘密鍵)で送信者が言い換えた結果(C)"と、"秘密鍵の対である公開鍵(D)"を受け取り、
> "受け取った証明書(A)から受信者が自分で計算したハッシュ(E)"と、"証明書から送信者が計算したハッシュ(B)を送信者しか持ちえない鍵(=秘密鍵)で言い換えたであろう結果(C)）を、送信者から受け取った鍵(=公開鍵)(D)で元に戻した結果(F)"が一致するかを受信者が確認する
> 一致したということは、「この言い換えは、自分が受け取った鍵(=公開鍵)と対になる鍵(=秘密鍵)を持っている人でしかできないはずだ」ということがわかります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/507249/8deb8784-1fcd-2525-a27c-539556f56a39.png)

ここで急に具体例（デジタル証明書とデジタル署名のしくみ）を挙げてしまっていますが…
まず大前提として、「公開鍵」は誰もが持っている周知の事実です。つまり、「秘密鍵で言い換えられたデータ」は、公開鍵を使えば誰もが元に戻せるのです。
誰もが元に戻せるようなデータを、はたして「暗号」と呼べるでしょうか……？

そもそも「デジタル署名」の場合、「秘密鍵で言い換える前のデータ」も、「秘密鍵で言い換えた後のデータ」も、どちらも併せて一緒に送信するので、暗号がどうとか、機密性がどうとか、という意図にはそぐいません。
つまり、「秘密鍵で暗号化」と言っている人は、「何かしらの鍵を使ってデータを言い換えること」を「暗号化」と勝手に呼んでしまっているだけで、その行為が意図する意味を言い換えているわけではないと推測しました。

ちなみに、この検証行為によって、この署名が、検証者本人が持っている公開鍵と対になる鍵を持っている人が行った行為であるということ（真正性）が確認できるとともに、署名者が署名したときの証明書と、検証者が受け取った証明書の内容に相違ないこと（＝途中でデータが改ざんされていないこと、完全性）も同時に確認できます。

## 対応関係の図
これまでの話を整理すると、以下のような図で示すことができます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/507249/ec89c5b6-d4b5-01e0-dd7e-8be8a5a2ce9b.png)


# まとめ
「秘密鍵で暗号化する」という言い回しに存在するモヤモヤを解消できました。
また、そのモヤモヤの本質は「秘密鍵を使ってデータを言い換えた結果は、その性質上「暗号」と言うには無理がある。「暗号」を作ることを「暗号化」というのであって、"何某かの情報を使ってデータを言い換えること"を安直に「暗号化」と言ってしまうことは早とちりである」ということだと理解できました。

似た記事が多く存在する中、自分もこのすっきり感を誇示したいが為だけに、わざわざ記事にして投稿してしまいましたが、個人的にはとってもスッキリしました。
この記事が誰かの参考になれば幸いです。

## 参考資料

とても勉強になる。

https://qiita.com/TakahikoKawasaki/items/4c35ac38c52978805c69#4-%E8%87%AA%E5%B7%B1%E7%BD%B2%E5%90%8D%E8%A8%BC%E6%98%8E%E6%9B%B8%E4%BD%9C%E6%88%90