公開鍵暗号関連のテキストの間違いの典型例

# はじめに
## 背景
世間一般の公開鍵暗号関連の解説書・サイトは99%あてになりませんが、一例として、とある情処対策の解説動画の添削を行います。
※twitterで問題点を説明する機会があったので、折角なら記事として共有できる形にしようという動機からです。

## 対象
対象の動画は https://www.youtube.com/watch?v=rgK4FGENzMo で、2021/3/1時点の内容を元にしています。
※後日修正される可能性もあるため。

なお、先に断っておくと、この動画が特別酷いわけではなくて、大体どれもどんぐりの背比べです。如何にみんな真面目に情報を検証していないか、ということが実感できます。

# 動画のスライドの添削
## スライド1: ディジタル署名(～0:48)
### 第1段落「公開鍵暗号方式を使って」
> ディジタル署名とは、公開鍵暗号方式を使ってデジタル文書の正当性を保証する技術です

この表現自体が間違いではないと言い訳できるけど、解説している人は「公開鍵暗号の暗号化機能を応用して」と勘違いしていることが、後の説明で分かる。なので問題。
正しくは「デジタル署名は公開鍵暗号の一種」で、理解してる人はスライドのような紛らわしい表現は使わない。

※注意:

* 皆のよく言う「公開鍵暗号」は「公開鍵暗号の『守秘』(暗号化機能)」に限定した狭義の用語、「デジタル署名」は「公開鍵暗号の『署名』」で、類似の別ジャンルの技術  
  参考: [CRYPTREC暗号リスト](https://www.cryptrec.go.jp/list/cryptrec-ls-0001-2012r5.pdf)の技術区分
* ただし、デジタル署名の最初のアイデアは公開鍵暗号(暗号化)とセットで出ているので、歴史的な話として「暗号化機能を応用して署名を実現するアイデアがあった」のは間違いではない。  
  実際に RSA という方式に限っては、そのアイデアを実現しているため、暗号化・署名の両用になっている。

### 第2段落「発信元が正しいか」
> ディジタル署名では確認できるのは、「発信元が正しいか」と「改ざんの有無」の2点です。

この内の「発信元が正しいか」については、情処の回答的には一応正しいけど、注意を要する表現。
「署名を作成したのが鍵の持ち主本人である」ことは分かるけれど、それが「発信元が正しい」とは等価ではないから。

例えば、AからBに「Aの署名付きメッセージ$M_{ab}$」を送っていたとして、その後Cが$M_{ab}$を誰かから受け取った場合。
署名付きだからといってAから受け取ったとは限らない。Bから受け取っている可能性がある。
※社長印を押した書類を持ってきた人が社長本人とは限らないのと同様の話

この場合、「メッセージの内容がB向けだからCはおかしいと気付ける」という対策がセットなら初めて「発信元が正しい」かどうかを判断できる。( メールに対する署名で重要 )

###【手順】の説明
> (略)
> この「ハッシュ値」を秘密鍵で暗号化する、これを「デジタル署名」と言います。
> (略)

よくあるデマ。下の説明以上のことは言えない。実現方法は様々であるため。

* 「対象のメッセージ」から「秘密鍵」を用いて「署名」を作る ( 署名処理 )
* 「対象のメッセージ」と「署名」に「公開鍵」を用いて、署名が正しいかどうかを調べる ( 検証処理 )

※注意:

* 各処理でメッセージ(+α)からのハッシュ値計算があるのは確かで、それは追加してもよい
* なお、暗号化・署名が両用のRSAの場合でも「秘密鍵で暗号化」を行うわけではない

### スライド1の補足
デジタル署名を「発信元が正しいか」と「改ざんの有無」の2点で説明するのは、本来筋が悪い。
単純に「(鍵の持ち主が)特定のデータを『保証』した証拠の実現」であるから。
現実世界の「自筆署名」「印鑑」と全く同じ位置づけで、「特定の人しか作れないが、誰でも本物と確認できる、という特徴を実現したモノ」をデジタルデータとして実現した技術と言える。
「特定の人しか元に戻せないため機密を扱うのに使える」という、公開鍵暗号の暗号化機能とは技術特性が異なる。

この「保証」が指す意味は、使われる場面によって何とでも意味を変えるところだが、例えば「コード署名」と呼ばれる使われ方なら、鍵の持ち主がアプリベンダだとして、「ベンダAがアプリのexeファイルFが正式リリース版(βとかかも知れないが)であることを保証します」というような意味を持つ。
これは、A以外の配布ベンダがファイルFを配布しても変わらない。つまり、直接の送信者と署名者が一致するとは限らない。

注意:

* 「大元の発信者が正しいことが分かりますよ」という話なら問題ない。
* 念ののため、「『発信者=データ作成者』とは限らない」ことにも注意。

ところで、もし対象のデータと署名の組み合わせがおかしければ、公開鍵を使うことで気付ける。
一般にこのことを指して「改ざんの有無が確認できる」と言っていて、別に間違いではないけど、ポイントはそこではなくて「保証があるかどうか」が一番重要なところである。
※セキュリティ用語的には、「保証する」ではなく「否認する(しらばっくれる)ことができない」ということで「否認防止」と表現する。

## スライド2: 公開鍵暗号方式とデジタル署名(～2:40)
### スライド2全般
  スライド1の【手順】で間違えているため、このスライド自体がナンセンス
### スライド2の補足
「秘密鍵・公開鍵どちらの持ち主が先に処理するか」という観点で、公開鍵暗号の暗号化機能と署名(デジタル署名)が真逆なのは確かだけど、記憶力を使って暗記するような大それた話ではない。
なぜなら、「秘密鍵は当人しかできない処理を行うためにある」という基本に沿って考えれば明らかな話だから。

* 「暗号化」なら「受け取った人にしか内容が分かって欲しくない」つまり「受信者しか復号できない」→ 受信者が秘密鍵を使う
* 「署名」なら「送信する人がデータに保証を与える」つまり「送信者しか署名する意味がない」→ 送信者が秘密鍵を使う

## スライド3: デジタル署名2(～4:18)
### スライド3全般
> ⑤平文からハッシュ値を求める
> ⑥ハッシュ値を秘密鍵で暗号化する
> (略)
> ⑧ディジタル署名を公開鍵で復号
> ⑨平文を送信者と同じハッシュ関数を使ってハッシュ値を求める
> ⑩比較して一致すれば送信者とデータが正しいと判断

⑤,⑥を「送信データから秘密鍵で署名作成」、⑧,⑨,⑩を「送信データと署名を公開鍵で(署名)検証して成功すれば、送信者とデータが正しいと判断」とすれば間違いではない。

### スライド3の補足
前述の通り「送信者が正しいか」は、メールに対する署名では大きな目的として言えなくもないけど、直接的な機能ではないことと、「データの内容に注意を要する」ことに注意。

## スライド4: SSL通信(～6:57)
### スライド4全般
> (略)
> ③共通鍵を公開鍵で暗号化
> (略)

今のSSL/TLSで「共通鍵を公開鍵で暗号化」はしない。基本的な知識の欠如と言える。

### スライド4の補足1
最新の規格でなければ「共通鍵(の元)を公開鍵で暗号化する」という選択肢は一応ある(あった)。
なので「最新の情報ではない」「1例の教示」という断りつきなら許容範囲とは言える。

ただし、サーバの持つ公開鍵・秘密鍵の主目的は暗号化関連ではないので筋が悪いし、そこをちゃんと補足する必要がある。
主目的は、「秘密鍵でしかできないことをしてみせることで本物のサーバであることを示す」( サーバ認証 ) ということで、今は基本的にデジタル署名でこれを行う。

### スライド4の補足2
通信の暗号化に共通鍵暗号を用いるのは間違っていない。
しかし、共通鍵の共有には「鍵交換(鍵共有)」と呼ばれる、別種の公開鍵暗号を使うのが一般的。
※これは情処の範囲外と思われる

### スライド4の補足3
サーバの公開鍵 ( サーバ認証用 ) は裸で送るのではなく、デジタル証明書(サーバ証明書/SSL証明書)の形で送る。
その説明がないのはちょっと問題。
あと、「内容の改ざんの有無」の説明が不適切。これはデジタル署名ではなく、MAC ( 今は共通鍵暗号とセットにした AEAD という方式 ) で担当する。

## スライド5: S/MIME(～8:03)
### スライド5全般
細かい部分を除いて概ね間違っていない。
ただ、微妙な点が若干あるのと、S/MIMEで使う公開鍵が、デジタル証明書(公開鍵証明書)の形になっている点を説明していない点は不十分に感じる。

### 「なりすまし」の対策
> なりすましに対して: 電子署名で対策

電子署名(デジタル署名)で対策、は間違っていないが「発信元の正しさ」に関しては、前述の注意と同じことが言える。

### 「改ざん」の対策
> 改ざんに対して: 暗号化と電子署名で対策

「暗号化」は関係ない。電子署名(デジタル署名)のみ。

### スライド5の補足1
情処の試験的には「公開鍵暗号でメールを暗号化して送ります」というような説明が出てくるが、実際は「公開鍵暗号による共通鍵の暗号化 + 共通鍵暗号によるメールの暗号化」のハイブリッドになっている。( そこまで気にしなくても良いけど )

### スライド5の補足2
「RSA と呼ばれる方式が使われる」のは概ね正しいけど、RSAである必要はない。

注意:

* RSAは暗号化・署名の両用ができるので都合がいい、というか、S/MIME自体がRSA以外を使うことをあんまり真剣に考えてなかった節がある。
* 最新の規格だと楕円曲線暗号にも対応していて、これだと「公開鍵暗号による共通鍵の暗号化」は行わない。  
  ※ただソフトの対応は結構遅いので、実装上対応していない可能性はある
* 代わりに、SSL/TLSの所でも触れた「鍵交換」を使う。楕円曲線暗号には、「鍵交換」「署名」を同じ鍵で賄える方式の組み合わせ(ECDH+ECDSA)があるため。

## スライド6: CA(～9:47)
### スライド6の全般
ちょっと説明に近視眼的なところがある。
ただし、「公開鍵が正しいものであることを保証する」、言い換えると「ある公開鍵 K の所有者が X であることを保証する」という役割についてはその通りで問題ない。

### 特徴の2項目目
> 「デジタル証明書」をデジタル署名に付加することで、「公開鍵が正しい」と証明されます

デジタル証明書は、公開鍵暗号(署名/鍵交換/守秘)全般に対して鍵の正しさを保証する技術なので、「デジタル署名に付加する」は関係ない。証明書+CA証明書だけで正しさが保証される。

この部分については、「CAがCA自身の作ったデジタル署名を証明書に付与しているため、当人の公開鍵が正しいと証明されます」という説明をすべきところが、何かの間違いでねじ曲がっているような気がする。
※これも「デジタル署名」の「保証」の典型的な用法の1つ

### 特徴の3項目目
> ユーザー(受信者)は認証局(CA)を介して、データの制作者を証明できます。

「制作者」ではなく「製作者」ではないだろうかと思うけど、そこは置いておいて2つの点で問題がある。

前述の通り、鍵の種類は署名/鍵交換/守秘の3通りあるので、用途を明確にしないとはっきりしたことは言えない。これが1点目。
※このスライド自体がおそらく署名用の鍵の保証の話を前提にしているけど、幾つかある用途の内の1つということを明言していない。

そして、署名を前提にしているとしても、それでも「署名者が誰か」を証明できるだけで、署名対象データの出自については何も言えない。これが2点目。
※私がネットで拾った画像に署名を施して配布したら、その画像を私が作ったことになるか、と考えてみれば、おかしいことが分かると思う。

### スライド6の補足1
デジタル証明書には、用途に沿って様々な種類があるのでそこに触れてないのは不十分な気がする。
例として、以下に挙げるような証明書がある。

* SSL/TLSで出てきた「サーバ証明書」  
  ※他にも、クライアントの本人確認に使う「クライアント証明書」もある
* S/MIME(メール保護)用の証明書
* コード署名で使う「コードサイニング証明書」  
  ※[スライド1の補足](#スライド1の補足)の説明を参照のこと
* CAが自分自身の鍵を配布するための「CA証明書」

### スライド6の補足2
SSL/TLSの「サーバ証明書」は、今は専らデジタル署名用途だけど、これは何かのコンテンツに保証を与える意味ではなくて「署名を作れることを示して本物のサーバであることを証明する」という用途で使われる。

## スライド7: それぞれのセキュリティ方式の機能(～最後)
### スライド7全般
単なる表なので、そんなツッコむところはない。
ただし、SSL/TLSの「完全性」はMAC(AEAD)で実現しているので、「SSL証明書」というカッコ書きは誤り。

# 終わりに
正直、プロだったらもうちょっと真面目に情報検証してほしい、というのと、デマ垂れ流し続けるのはなんとかしてほしい、と思うものの、個人的には期待できる気がしません。
単に試験で得点を確保するだけなら、別にどう覚えようと個人の自由だとは思いますが、真面目に知識を生かすことを考えるなら、各自対処を考えた方が良いと思います。この記事がその一助になれば幸いです。