ファイルを GPG で暗号化して保存する

## やりたいこと
とある大きめのファイルを，人に見られない形で保存したいことがあった．せっかく [以前の記事](https://qiita.com/kino-ma/items/c5679997293cbbd34b34) で紹介したように GPG に入門したので， GPG で暗号化して保存することにした．

## やること (TL;DR)
暗号化する時は，以下．出力は `入力ファイル名.gpg` になる．

```sh
$ # optional
$ tar czvpf <COMPRESSED_FILE_OUT.tgz> <PLAIN_FILE>...
a <PLAIN_FILE>
$ gpg --encrypt-files \
        -r <RECIPIENT> \
        <FILE_TO_ENCRYPT>
```

復号するときは，以下．

```sh
$ gpg --output <DECRYPTED_FILE_OUT> --decrypt <ENCRYPTED_FILE>
$ # 中身が tgz の場合
$ mkdir <EXTRACTED_DIR_OUT> && tar xvf <DECRYPTED_FILE> --directory <EXTRACTED_DIR_OUT>
```

## 詳しい手順
### 0. 暗号化する対象のファイルを用意する
今回はテスト用に， `hoge` と書き込んだテキストファイルを用意した．それだけではなんとなく味気ないので， 1024 バイトになるようにランダムバイト列を書き込んだ．

```sh
$ echo -n hoge > test
$ cat test
hoge
$ # 1024 - len(hoge) = 1020 バイトのランダム文字列
$ head -c 1020 /dev/urandom >> test
```

中身を確認すると，先頭に `hoge` があり，その後にランダムな文字列が並んでいることが確認できる．今回はこのファイルを暗号化の対象とする．

```
$ xxd test | head
00000000: 686f 6765 e24b 35a2 3967 c9fa ac6e 1a4e  hoge.K5.9g...n.N
00000010: 1df3 5695 e635 b14d 2b3e 6e3e 7762 773a  ..V..5.M+>n>wbw:
00000020: f534 f562 8395 4682 1919 ccc6 e6d4 0971  .4.b..F........q
00000030: 72a6 2301 55db 2cc2 e782 d89e a3f7 485b  r.#.U.,.......H[
00000040: 97b2 fd68 52f5 3ab2 b538 bcf8 a95b 5cb7  ...hR.:..8...[\.
00000050: 5239 7a1a 9810 6320 5655 7e5b 187c db5b  R9z...c VU~[.|.[
00000060: d7aa f7cd f004 95c1 960f c468 63d6 4ec5  ...........hc.N.
00000070: 3ad8 bb88 ff2f 0d2a 1b81 1b5e f68f ec49  :..../.*...^...I
00000080: ef55 70be 4e6d 7bfa 57f0 3916 889d bc97  .Up.Nm{.W.9.....
00000090: 8e17 1c11 a5f8 1d6c af4c 1504 835a 5661  .......l.L...ZVa
```

### (optional) 1. ファイルを `.tgz` 化する
対象となるファイルが大きい場合など．

```sh
$ tar czvpf test.tgz test
a test
```

この段階では，以下のように人間には読めないが，単に gzip 化された tar ファイルなので，簡単に中身を見ることができる．

```sh
$ # 人間には読めない
$ xxd test.tgz | head
00000000: 1f8b 0800 3fb8 ec61 0003 2b49 2d2e 61a0  ....?..a..+I-.a.
00000010: 3130 3030 3033 3151 00d1 e666 a660 1a08  1000031Q...f.`..
00000020: 60b4 8111 8863 6862 686e 6c68 6c6c 6a6a  `....chbhnlhlljj
00000030: a860 6068 6462 62c2 a060 406b 8781 4069  .``hdbb..`@k..@i
00000040: 7149 6211 d029 d999 79f9 bab9 8938 d595  qIb..)..y....8..
00000050: 67a4 a6e6 e031 07d5 530a 5477 278d 4046  g....1..S.Tw'.@F
00000060: 7e7a ea23 6fd3 4596 e927 7fad c993 f293  ~z.#o.E..'......
00000070: fd1c 36f5 99e9 465f 6dbb 3cbb f2a4 72ab  ..6...F_m.<...r.
00000080: af26 5f93 9aa7 ba35 494a 9e39 f6ec 0a67  .&_....5IJ.9...g
00000090: 61d1 3265 c6d0 db3a 879e 37dd 98b7 f8bb  a.2e...:..7.....
$ # 簡単に展開できる
$ mkdir testx && tar xvf test.tgz --directory=testx
x test
$ ls testx
test
$ xxd testx/test | head
00000000: 686f 6765 e24b 35a2 3967 c9fa ac6e 1a4e  hoge.K5.9g...n.N # 先頭に "hoge"
00000010: 1df3 5695 e635 b14d 2b3e 6e3e 7762 773a  ..V..5.M+>n>wbw:
00000020: f534 f562 8395 4682 1919 ccc6 e6d4 0971  .4.b..F........q
00000030: 72a6 2301 55db 2cc2 e782 d89e a3f7 485b  r.#.U.,.......H[
00000040: 97b2 fd68 52f5 3ab2 b538 bcf8 a95b 5cb7  ...hR.:..8...[\.
00000050: 5239 7a1a 9810 6320 5655 7e5b 187c db5b  R9z...c VU~[.|.[
00000060: d7aa f7cd f004 95c1 960f c468 63d6 4ec5  ...........hc.N.
00000070: 3ad8 bb88 ff2f 0d2a 1b81 1b5e f68f ec49  :..../.*...^...I
00000080: ef55 70be 4e6d 7bfa 57f0 3916 889d bc97  .Up.Nm{.W.9.....
00000090: 8e17 1c11 a5f8 1d6c af4c 1504 835a 5661  .......l.L...ZVa
```

### 2. GPG を使って暗号化する
GPG の暗号化機能を使って暗号化する．復号できる人（＝受け取り手）として，自分に限らず他の人も指定することができる [^pubkey]．

[^pubkey]: 事前に受け取り手（開鍵を import しておく必要がある．

```sh
$ gpg --encrypt-files \
        -r ma@kino.ma # 受け取り手 \
        test.tgz
$ xxd test.tgz.gpg | head
00000000: 845e 0302 abde dc13 ab19 f412 0107 4074  .^............@t
00000010: fa08 754a f5d5 4576 a4de 1476 c187 7c80  ..uJ..Ev...v..|.
00000020: e6ed 8c18 e349 1a09 9a1e ba8d f940 6130  .....I.......@a0
00000030: e63d 6d11 ac84 44c5 8867 e4c1 ee16 80e4  .=m...D..g......
00000040: 1444 dacc b3fe 35e8 e20d 7478 32c2 4309  .D....5...tx2.C.
00000050: fae3 cc4a 5471 c2a1 5d86 806d 0b8a 5317  ...JTq..]..m..S.
00000060: d4ea 0109 0210 8238 1d4f 04f8 4cdb cacd  .......8.O..L...
00000070: 1869 69f9 0376 84cc c582 b55f 9fe6 b34f  .ii..v....._...O
00000080: 1962 c474 ba9c a3d1 65ac c3e6 0a6b 2482  .b.t....e....k$.
00000090: d543 e7d0 163f 8c83 e962 034c 6af7 abc7  .C...?...b.Lj...
```

この段階になると，受け取り手以外は `tar` コマンドや `gpg` コマンドを使っても解読することができない．

```sh
$ mkdir testxc && tar xvf test.tgz.gpg --directory=testxc
tar: Error opening archive: Unrecognized archive format
$ # 秘密鍵を持っていない場合
$ gpg --decrypt test.tgz.gpg
gpg: encrypted with ECDH key, ID 02ABDEDC13AB19F4
gpg: decryption failed: No secret key
```

### 3. 復号する
暗号化したファイルを読みたくなった時には，まず復号する必要がある．

```sh
$ gpg --output test-decrypted.tgz --decrypt test.tgz.gpg
gpg: encrypted with cv25519 key, ID 02ABDEDC13AB19F4, created 2021-11-14
      "kino-ma <ma@kino.ma>"
$ mkdir testxd && tar xvf test-decrypted.tgz --directory=testxd
x test
$ xxd testxd/test | head
00000000: 686f 6765 e24b 35a2 3967 c9fa ac6e 1a4e  hoge.K5.9g...n.N
00000010: 1df3 5695 e635 b14d 2b3e 6e3e 7762 773a  ..V..5.M+>n>wbw:
00000020: f534 f562 8395 4682 1919 ccc6 e6d4 0971  .4.b..F........q
00000030: 72a6 2301 55db 2cc2 e782 d89e a3f7 485b  r.#.U.,.......H[
00000040: 97b2 fd68 52f5 3ab2 b538 bcf8 a95b 5cb7  ...hR.:..8...[\.
00000050: 5239 7a1a 9810 6320 5655 7e5b 187c db5b  R9z...c VU~[.|.[
00000060: d7aa f7cd f004 95c1 960f c468 63d6 4ec5  ...........hc.N.
00000070: 3ad8 bb88 ff2f 0d2a 1b81 1b5e f68f ec49  :..../.*...^...I
00000080: ef55 70be 4e6d 7bfa 57f0 3916 889d bc97  .Up.Nm{.W.9.....
00000090: 8e17 1c11 a5f8 1d6c af4c 1504 835a 5661  .......l.L...ZVa
```

先頭に `hoge` と書かれているので，正常に読めていることがわかる．

## まとめ
何らかのファイルを `.tgz` 化し，さらに GPG で暗号化する手順を説明した．この手順を使って，任意のファイルを暗号化して保存することができる．