子供と遊びたい~OpenSSLを使った暗号技術ハンズオン

# OpenSSLの基本コマンドを身に付ける遊び
## 目的: 共通鍵暗号で子供と遊ぶ
仕事で少しだけOpoenSSLを使う機会があり、ちょっとだけ勉強しました。いくつかサブコマンドとオプションを覚えるだけで暗号化・復号化の遊びが気軽にできることを知り、感動したことが切っ掛けで、これならば中学生の子供に暗号の仕組みを教えつつ、自分も遊べるな、と思いました。この記事はそのためのメモとして残しています。（まだ自分は子供と遊べてません。）
業務的な小難しいPKIベースのシステムから一旦離れて、opensslで遊んでみましょう。

## 共通鍵暗号で遊ぶ
遊びなので実用的な暗号強度は無視して、単純にコマンドをタイプし易いという理由で[DES](https://ja.wikipedia.org/wiki/Data_Encryption_Standard)のアルゴリズムを使います。
### 使用機材
+ Mac or PC 2台 (子供と自分用1台ずつ)
+ ファイル交換をするためのメッセージアプリをそれぞれインストール。
+ opensslをそれぞれインストール。

### 使うopensslコマンドとオプション
+ DES暗号化: `openssl des`   # 暗号鍵はプロンプトでキーボードで手入力。
+ DES復号化: `openssl des -d`

### 遊んでみる
暗号化したメッセージをファイルにして、相手に送りましょう。
#### 暗号化
相手に伝えたいメッセージを下のコマンドで暗号化します。プロンプトで求められて入力するパスワードは数字などの簡単なものにして覚えておきましょう。("123"など)
暗号化されたファイルは`des.dat`のファイルにバイナリデーターとして保存されます。

```bash:DESアルゴリズムで暗号化
$ echo "秘密のメッセージだよ！" | openssl des > des.dat
enter des-cbc encryption password:<パスワード入力>
Verifying - enter des-cbc encryption password:<パスワード入力>
```
#### メッセージ交換
適当なメッセージアプリケーションを使って相手に送りましょう。メッセージが暗号化されて内容が分からないことを確認してみましょう。

```bash:暗号化されたファイルの中身が全く判らない様子
$ cat des.dat
Salted__??̫3j?ov?Cʔ?]??U+R?Q@D??
                               ??
$ hexdump des.data 
0000000 53 61 6c 74 65 64 5f 5f 80 9b cc ab 33 6a 05 1a
0000010 d5 6f 76 f3 43 ca 94 05 ea 5d c9 f9 55 2b 52 85
0000020 51 40 44 ee c1 0c 94 e3
```
#### 暗号鍵（パスワード）を相手に教えて復号化
メッセージの内容がそのままでは分からないことを確認してから、正しいパスワードを入力して復号化しましょう。間違ったパスワードを入力すると、復号化できないことも確認すると良いと思います。

```bash:相手から聞いたパスワードがあれば復号化できる。
$ cat des.data | openssl des -d
enter des-cbc decryption password:<正しいパスワードを入力>
秘密だよ！
```
---
## 公開鍵暗号で遊ぶ
実用的でタイプも短い[RSA](https://ja.wikipedia.org/wiki/RSA%E6%9A%97%E5%8F%B7)を使います。
### 使うopensslコマンドとオプション
+ RSA秘密鍵作成: `openssl genrsa`
+ RSA公開鍵作成: `openssl rsa -pubout`
+ RSA暗号化: `openssl rsautl -encrypt -pubin <公開鍵ファイルパス>`
+ RSA復号化: `openssl rsautl -decrypt -inkey <秘密鍵ファイルパス>`

### 遊んでみる
#### RSA秘密鍵・RSA公開鍵の作成
下のコマンドでRSA秘密鍵を作成します。作られた秘密鍵は`private.pem`のファイル名で保存されます。

```bash:秘密鍵を作成
$ openssl genrsa > private.pem
Generating RSA private key, 2048 bit long modulus
................+++
.....................................................................+++
e is 65537 (0x10001)
$ cat private.pem 
−----BEGIN RSA PRIVATE KEY-----
MIIEpAIBAAKCAQEAzA4NUHD8ws5yK9OqqdGgWi6bEGX8Pol8GmklQ1O2f5udfwF3
EmmwKY6bMXeT8asIdTB/OC/msNBWcynUx6PrqU7hJrw9QJxu6UNijpT+q7LAUV7I
<中間略>
P2QCwhlmQrcN3ZTEhsAvc789MQnDimUCEzHka8JPfVQ5IWBBDzvCwmnwrrLZM0LT
fEZImofP55hjZjFu8KTa7kfXcC5HKCScrSGXKCqOt6WEXSB6aeljKA==
−----END RSA PRIVATE KEY-----
```
たった今作成した秘密鍵と対になる公開鍵を作ります。公開鍵は`public.pem`のファイル名で保存されます。この公開鍵はメッセージを交換したい相手に渡すものです。

```bash:暗号化されたメッセージを交換したい相手に渡す公開鍵の作成
$ cat private.pem | openssl rsa -pubout > public.pem
writing RSA key

$ cat public.pem 
−----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAzA4NUHD8ws5yK9OqqdGg
Wi6bEGX8Pol8GmklQ1O2f5udfwF3EmmwKY6bMXeT8asIdTB/OC/msNBWcynUx6Pr
<中間略>
XzK453nOK5NtVIO1339H5cQpXfnPmUv1d30ZOHMzUAOuCm1L8Fre2PY5K1PJ1Xdj
CQIDAQAB
−----END PUBLIC KEY-----
```

#### 公開鍵をお互いに鍵を交換
それぞれ作った公開鍵(`public.pem`)をメッセージアプリを使って交換します。相手から受け取った公開鍵`public.pem`は次のステップのメッセージの暗号化で使います。

#### 暗号化メッセージ作成
__自分のではなく、相手の公開鍵__を使って、相手に送るための暗号化メッセージを作ります。
下の`public.pem`は相手から受け取った公開鍵のファイルなので、注意してください。下のコマンドで暗号化されたメッセージファイル`rsa.dat`が出来上がります。中身がそのままでは読める状態でないことも確認します。

```bash:相手から受け取った公開鍵を使って自分のメッセージを暗号化する
sh
$ echo "絶対秘密やで〜" | openssl rsautl -encrypt -pubin -inkey public.pem > rsa.dat
$ cat rsa.dat
:?K??S?I????m+C?Z?????x??oUbsOé_A*?)Pܓ???@
                              ??I?Hy?O?}?gqQ??????FxÙ??2? Y?-	?qv?S???mn??a>d??tM?g!????_?:Yi???P+??u
                                                                                                       ?w???q?g???"??߁_?q?6U???2Z ?"???|??[?\?????V4??z_???L?fJi??q?C?Ϋ???O?o]?y???[?
$ hexdump rsa.dat
0000000 0e e9 f9 a1 4c 57 e7 19 88 ac 82 86 65 46 49 80
0000010 07 5d 33 38 e5 7d fb 48 c1 f9 6c 4e 14 36 f6 b3
0000020 b5 dd c3 a9 5f 1a 41 2a fe 16 29 50 dc 93 b2 af
0000030 8f 40 0d 3a c5 4b ad cb 53 8d 49 e2 c0 a2 96 6d
0000040 2b 43 05 81 5a b5 a9 1c 8a db d9 78 f2 94 05 a9
0000050 6f 55 62 73 4f 0b bb c1 49 85 48 79 8d 4f e9 7d
0000060 ae 67 71 1a 51 e7 e9 f9 a1 9c d7 46 78 c3 99 a4
0000070 a2 01 32 cf 20 59 d3 2d 09 b9 71 76 b0 53 d4 15
0000080 98 f9 6d 6e c6 fc 61 06 3e 64 ee dc 74 4d f9 67
0000090 21 f3 90 c1 eb b8 00 a1 5f c9 3a 59 69 9f d7 cd
00000a0 50 2b 8e 9a 75 0b a4 77 18 e7 e9 8a 1a 90 71 a6
00000b0 67 a8 b6 e6 22 cb c9 df 81 5f c1 71 ff 1d 36 55
00000c0 bb f1 f4 32 5a 20 98 22 ff 9b 92 7c fb 97 04 5b
00000d0 d4 5c e2 ed a8 ca c9 56 34 b9 c9 7a 5f fe ba 02
00000e0 d9 4c 8f 66 4a 0e 69 f9 ef 71 ee 98 43 f4 ce ab
00000f0 9d 91 8e 4f 99 6f 1c 5d fb 79 f9 dd ed 10 5b 8f
```

#### 暗号化されたメッセージ交換
メッセージアプリを使って、それぞれが作った`rsa.dat`ファイルを相手に送ります。

#### 受け取った暗号化されたメッセージを復号化
相手から受け取った暗号化されたファイル、`rsa.dat`と自分の秘密鍵を使って、復号化して読めることを確認します。

```bash:自分の公開鍵を使って暗号化されたメッセージは、自分の秘密鍵で復号化できる
$ cat rsa.dat | openssl rsautl -decrypt -inkey private.pem 
絶対秘密やで〜
```
## さいごに
以上、最小限の暗号技術のハンズオンでした。この記事を見ながら中学生の子供とトライしてみたいと思います。