公開鍵暗号使ってTwitterで恥ずかしいことをいってみる。

# 王様の耳はロバの耳
エライヒトの悪口とか、言ってはいけないこととか、そういうことって大っぴらにいうと気持ちよくないですか？僕は気持ちいいです。一方で、そんなことを大っぴらにいって自分の上司とかにみられるのもちょっと困ってしまいますね。
そんな欲望を一気に発散するために

**ツイッターの中心で愛を叫ぶ。でも誰にも内緒で**

をやってみたいと思います。

## おことわり
技術的な方法の解説を、おもしろおかしく記事にするのが目的です。実際にこの方法で投稿を繰り返して発生する様々な問題について当方は一切の責任を追いません。

## 前提事項

|No.|項目|前提|備考|
|--|--|--|--|
|1.|OS|Windows |一部Windows独自のコマンドを利用します。|
|2.|導入ソフトウェア|OpenSSL|暗号全般、すべてこのコマンドで実施します。OpenSSLの導入方法は別途説明します。|


## Alice  と Bobのお話

なぜか、通信するのはいつもAliceとBobなんですよね。秘密鍵を利用したメッセージのやり取りはこんな感じで行います。

![openssl.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/837176/8203c155-1544-68d1-b0ca-76eb3beb4be5.png)

### 1. 鍵の生成

まずはお互いが使う鍵を作ります。公開鍵暗号は、共通鍵で暗号を作り秘密鍵で開きます。共通鍵を持っていても開くことはできないのがポイントです。**なので自分で書いたことを自分では見ることができなくなる**面白おかしい事が発生しますｗ

|No.|作業|概要|
|--|--|--|
|<1>|秘密鍵を作る|今回はOpenSSL使って、RSA 2048バイトの鍵を作成します。この鍵であけるための共通鍵を作る必要があるので、先に秘密鍵が必要なんです。|
|<2>|共通鍵を作る|1.で作った秘密鍵で開ける暗号文をつくるための共通鍵を生成します。|
|<3>|共通鍵を送る|鍵をかけてメッセージを送ってもらう必要があるので、この鍵を **何らかの方法で** 送ってもらわなければなりません。ここで誰かに抜き取られると、送信元を「なりすまされ」るのです。<p>他にもいろいろと問題があるので**鍵配送問題**は共通的なテーマです。</p>|

なお、Windowsが前提なので**作業は全部コマンドプロンプトです**

#### 1-0 作業ディレクトリをつくろう

```
mkdir c:\dev\workspace\secret
mkdir c:\dev\workspace\secret\keys
cd c:\dev\workspace\secret
```

以後の作業は全てc:\dev\workspace\secretで実行することが前提です。ご注意ください。(といってもリダイレクト先ぐらいの話ですが)

#### 1-1 秘密鍵を作ってみよう

まず秘密鍵を生成します。

```
openssl genrsa 2024

```

openssl は genrsa サブコマンドでRSA方式の秘密鍵を生成します。鍵の長さは2024バイトとします。これは近年1024バイト長の鍵では柔らかすぎると言われ始めたからです。(情報処理安全確保支援士あたりで時々問題になります。)。

鍵は生成されるのですが、これ、標準出力に出てしまうのでこのままでは再利用できません。なにせ僕、記憶力喪失っていわれるぐらい記憶できないんで。

**標準出力に出るのなら、リダイレクトしてしまえばいいのです** 

```
openssl genrsa 2024>keys\secret.key
type keys\secret.key
```
#### 1-2 共通鍵を作ってみよう

次は秘密鍵ね

```
openssl rsa -pubout < keys\secret.key
```

openssl rsa コマンドに -puboutオプションを与えて実行します。標準入力で秘密鍵の入力待ちを実施するので、秘密鍵の内容をリダイレクトして渡します。やはりこの場合も、共通鍵は標準出力されるので、リダイレクトで受けてあげましょう。

```
openssl rsa -pubout < keys\secret.key > keys\public.key
type keys\public.key
```

#### 1-3 鍵を渡そう

この鍵を渡してあげることでaliceはbobのために鍵をかけたメッセージを作れるようになります。必要に応じてメールその他の方法で渡してあげてください。

### 完了状況

こんな感じになってるはず。

```
c:\dev\workspace\secret>dir /s /b /A-d
[ 確認結果 ]
c:\dev\workspace\secret\keys\public.key
c:\dev\workspace\secret\keys\secret.key
```

### 2. メッセージを送る

さて、次はメッセージの送信です。みなさんAliceの立場で読んでくださいね。環境いじるの面倒なので、Alice もBobからもらった共通鍵をkeys\pulic.keyとしておいているという前提です。

|No.|作業|概要|
|--|--|--|
|[1]|メッセージを作成する|送信したいメッセージを作ります。|
|[2]|bobの公開鍵で暗号化する|1で作ったメッセージを暗号化します。|
|[3]|Base64でエンコードする|[2]の結果はバイナリデータなのでテキストエディタでのコピペができません。ツイッターに張り付けるためには、文字列出なければいけないのでBase64でエンコードします。|

#### 2-1 メッセージを作成する
echo でメッセージを作ってもいいんですけど、めんどくさいのでnotepadで作ります。

```
notepad message.txt
```

こんな感じにメッセージを書いて保存。保存するとき、文字コードがUTF-8 になっていることは確認してくださいね。

![notepad.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/837176/b4725bab-7891-ab19-bb67-5341ea091992.jpeg)

お勧めは自分の**大好きな女の子の名前**とか。そういうのが楽しいです。だってどうせ誰も読めないんですから。えっと、断っておきますが。このテキストを**そのまま** つぶやいてはいけませんよ？？？みんなにバレちゃいます。

### 2-2 bobの公開鍵で暗号化する

みなさんお待ちかねの**暗号化たーいむ**。早速いってみましょう。これもopensslでできちゃいます。rsautlサブコマンドを使います。それぞれのオプションの意味合いは、 **-ecrypt** オプションで「これから暗号化するよ！！」と宣言し、**-pubin**で「鍵は共通鍵だよ」 **-inkey**で「鍵はこれだよ」と教えてあげているだけです。素敵なツールですね。ほんとありがたい。

例によって、入力は標準入力なので、先ほど作ったファイルの中身を標準出力に出力し、パイプで渡します。(typeはファイルの中身を読み上げるLinuxのcatみたいなコマンドですね。)

```
type message.txt |openssl rsautl -encrypt -pubin -inkey keys\public.key

[結果]
t･ﾌ話<・o2i｢m・ﾔE澆能Eｿﾑy・ｺ|ﾀｫﾋ[ﾋ・・ﾊ・・ﾎﾏDｶ=&ｧﾎ7B櫂・ｵ・+・ﾅH}ｧXｾEｫ6#ﾝBp・癨ﾐS~・^+・+・ﾉ浯;ﾖｿs・c謄・A>       ﾅ燬ﾂ2叉・.・>?gW・DｫｸｶHﾜp,ﾞﾟ窕]ﾁnﾇ・=・ｨ\ﾂcＲ・ﾂT窰tO       {ｷg艸x､限#ｿ・ﾒ槃#ｷ_$ｻ) j尞ｷDｲZﾋ柤益>>ﾙ繋ュ迹eｺ倹釗T24;ﾞｾﾕ

```

こういうの見るとみんな「**文字化け**」とか変なこというんですよね。文字化けというのはもっと別のもので、こんな「バイナリを無理やりテキストでみた」ときに発生しているのは「文字化け」とはいいません。だってそもそも文字ですらないのですから。。

なので、標準出力をリダイレクトして、いい感じにファイルにしちゃいましょ。

```
type message.txt |openssl rsautl -encrypt -pubin -inkey keys\public.key > ecripteddata.dat
dir .
[結果]
 c:\dev\workspace\secret のディレクトリ

2022/02/12  11:32    <DIR>          .
2022/02/12  10:39    <DIR>          ..
2022/02/12  11:32               253 ecripteddata.dat
2022/02/12  10:56    <DIR>          keys
2022/02/12  11:20                70 message.txt
```

はい。暗号化済みのデータが作成できました。先ほどお話したようにこのファイルはそもそもテキストではないので、Aliceがツイッターにはっても、誰も読むことができません。どうしましょう。

**バイナリデータならテキストにエンコードしてしまえばいいわ！！！**

となります。こんな感じ

```
certutil -f -encode ecripteddata.dat encorded.txt
[結果]
入力長 = 253
出力長 = 408
CertUtil: -encode コマンドは正常に完了しました。
```
certutilを利用します。いろいろできるコマンドですが、今回はBase64のエンコード・デコードに利用します。 -f は入力をファイルとすること、-encodeはBase64でエンコードしてね。ということを意味します。できたファイルの内容を確認しましょう

```
type encorded.txt
[結果]

-----BEGIN CERTIFICATE-----
ru9/qUv+tWnFQB0FXHTAggsUWwW0xNqbfq3alz3LH0jbDN/JA2tPlyjY0j69KBjP
SaAIsb9cX1tso8M090dzKvtHE/1tDzW1d/vlOqhWWwdYUFPa16gaGCW/XGYnFHGi
74gHOj1HQFeot/BdMCG9MEhOmuGgncf1pXpQs03fsZNZJm/7fpCKAT6KZTY4RLpg
w7fOuMDaySJkqd6oyt4nLhIyzthOXsZgFlof5aSFlKN/A+yiN8udiqEG5jnFFCK0
H/+D8VgVaqDmyzfj7OkjdFnGJb1Jc+XR6fU4hLSEu34f6PoT3oJ7irVvsfGAU1PQ
TqxE2+7+9aVXHcj8mg==
-----END CERTIFICATE-----
```

ハイこんな感じになりました。メッセージの送信はこの文字列をツイッターにはってしまえばいいのです。ただし144文字の制限があるのでいい感じに2回に分けて送信してください。こんな感じですね。

![OnTwitter.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/837176/f23da87d-e53e-7b12-ab2e-fc8564c8d703.jpeg)

余談ですが、ときどき、文字列とかデータをBase64  形式で符号化することを「暗号化」と呼ぶ「あれ」な人もいますし。なんなら結構な確率でBase64で符号化した平文を「暗号パスワード」とかいって人もいっぱいいるので、残念な人なんだなと思ってかかわらないようにしましょう。その人やばいヒトです。

ここまででAliceはメッセージの送信を追えました。割と簡単ですね。

## メッセージを読む
さて、ツイッターをみたBobはこれがAliceからのメッセージだと気づきます。どきどきですね。読んでみたいのです。さっそく読んでみましょう。

|No.|作業|概要|
|--|--|--|
|[4]]|Base64でデコードする|もらったメッセージをファイルに保存し、Base64出でコードします。|
|[5]|bobの秘密鍵で復号化する|4の暗号文を秘密鍵で平文に戻します。|

## Base64でデコードする

まずはもらったファイルを1つのファイルに格納しましょう。

```
notepad messageFMAlice.txt

```
アリスからメッセージをこんな風に1つのファイルにまとめて。。。

![受領メッセージ.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/837176/57dd96d6-180f-62ac-5e91-41d7462945fa.jpeg)

保存します。

では早速、文字列にエンコードされたデータをバイナリに戻しましょう。

```
certutil  -f -decode messageFMAlice.txt messageFMAlice.dat
```

先ほどの逆なので説明不要ですね。作成される
## Bobの秘密鍵で復号化する。

最後にBobの秘密鍵を使ってmessageFMAlice.datを復号化します。

```
 type messageFMAlice.dat|openssl rsautl -decrypt -inkey keys\secret.key
```
rsautlに対して -decrypt=復号化してね -inkey=鍵はこれを使ってねと教えています。デフォルトで秘密鍵なので、鍵の種類を教えてあげる必要はありません。。結果は・・・ドキドキ・・・・

```
縺ｯ縺倥ａ縺ｦ縺ｮ繝｡繝・そ繝ｼ繧ｸ縲・
邇区ｧ倥・閠ｳ縺ｯ繝ｭ繝舌・閠ｳ・・ｼ・
```

あ・・・・こういうのを「化けた」というのです。いやうろたえてなんかないんだからね！！ホントにこれを見せたかったんだからね！！（嘘）

ウィンドウズのコマンドプロンプトはデフォルトでWindows-31Jという文字コードで文字を扱います。一方アリスはUTF-8でメッセージを作成したのでしょう。どうすればいいのかな。。。と考えると。「UTF-8」を正しく扱えるプログラム＝notepadに任せればいいと考えるわけです。そのためにはファイルにしないといけないので。


```
 type messageFMAlice.dat|openssl rsautl -decrypt -inkey keys\secret.key >decrypted.txt

```

最後にnotepadで。。

```
notepad decrypted.txt
```
![notepad.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/837176/b4725bab-7891-ab19-bb67-5341ea091992.jpeg)

無事みることができました。でもありすお前・・・・王様の耳はロバの耳って・・・・・

# まとめ

* OpenSSLは便利なツールで、これだけで公開鍵暗号を愉しむことができるよ。
* ツイッターに貼って遊ぶには文字データにデコードしないとだめだよ。
* ツイッターの本来の目的から離れてそうなので、運営になにされても文句言えないよ。
* 王様の耳はロバの耳だよ
* ツイッターの中心で愛を叫んでも全然恥ずかしくないよ

こんな感じですかね。愉しんでいただけたら幸いです。