はじめに : PGPはオワコン

ファイルをどう暗号化するか。

そもそも、暗号化は意図しない他人に内容を覗かれないするためのものである。
内容を覗かれないようにする目的を考えてみると、データが盗まれたときのため、安全でない経路を通して特定の人にデータを渡すため、である。

このうち、後者の「安全なデータ授受」についてだが、今時いろんな方法はあるものの、そもそも仕事場がモダンな通信手段を許可しておらず、メールだけ、あるいは会社製のファイル授受糞システムくらいしかない。

仕方なくパスワード付きzipをメールで送ることになるんだけど、これはいわば共通鍵方式でありリスクはある。
「パスワードは後のメールで送ります」なんてね。
ほんとに秘密のファイルを送るなら、公開鍵暗号を使いたい。

そうすると候補に挙がるのはPGPであるが、PGPは2020年時点でかれこれ30歳(1991年生まれ)でいろいろと古く、セキュリティ強度に不安があるうえに、使い方の理解が非常に難しく、そもそも鍵が長すぎるんだよ。

試しに「まあ安全」と言われるレベルの2048bitのPGP鍵を作ったらこんな感じである。
本来なら(略)とかするが、この場合PGP鍵の長さを示すのが目的なのでそのまま示す。
ぜひマウスホイールを狂ったようにカリカリしてスクロールしてほしい。
クレイジーである。

-----BEGIN PGP PUBLIC KEY BLOCK-----
Version: Keybase OpenPGP v1.0.0
Comment: https://keybase.io/crypto

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
6ceBrKxYJQvD
=DVAW
-----END PGP PUBLIC KEY BLOCK-----

こんなもん日常使いできるか。
世の中の皆さんもそう思っているようで、PGPのオワコンについてはPGP(Wikipedia)英語に怒涛の記載がある。
We’re calling it: PGP is dead (WIRED)は文字通りの記事。

PGPは捨ててage(アゲ)を使う。(他に道がないならば)

そんなわけでageである。
ageとは、「簡易でモダンで安全な暗号化ツール」だそうである。(https://github.com/FiloSottile/age)
Actually Good Encryptionの略。
読み方は「アゲ」。エイジではない。

PGPに比べれば、鍵は短いし、パイプで繋げられるし、簡単だしで確かにいい。
特に鍵の短さは特筆すべきものがある。
PGP鍵は話にならないが、sshの鍵と比べても短い。
sshの鍵は以下の通り。

ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDkldIB4qJ2iLN7OChd4DnTNlyYdbnYFVQh+nAC5EscgyQJ9cYjXXk+iKz0Ot7fb5+UYZsKzGwe6bri15ts+gl1rX7AlE1QORxUZUAM5bx4VXK3MDKIz6WHpjCRsYHD6gFiw0MTTQCPfrznLMFryfM6njhEqtetCUCJeCOrJtUPYJGKw4GJ7l3hlBfPxgwViVaGT55X3FcuwaAHPR54lS/MahMfF7FuhZDxrJj+azaISNup8w19QedWm7O26f0IyxzR6MJG+5KWxSn8DtI5a3RJ5s0CCEAgZiXmZG3Rlegbq7Vgmd9cjiM5mPjUrC0voJq4UOSydi92OGpAvIVpD7UL

一方、ageの鍵は以下の通りで、短いねえ。

age1rvvg4xt2f9rvkc0dthy5au7kg42jec355ayd24lmath0euzetsfs8czjff

ageはWindows, Mac, Linux, FreeBSDで使える。
ただ、現時点では単なるコマンドなんで、一般人とのファイル授受にはまだ使えないねえ。

では以下、インストールと使い方

インストール

githubの通り。
Windows, Mac, Linux向けにはバイナリもある。

FreeBSDならpkg install security/ageで。

FreeBSDでのageインストール(不要な人は飛ばせ)

とはいってもpkgでインストールするだけ。
取得サイズは1MiB。けっこう大きいね。

$ sudo pkg install security/age
パスワード:
Updating FreeBSD repository catalogue...
FreeBSD repository is up to date.
All repositories are up to date.
The following 1 package(s) will be affected (of 0 checked):

New packages to be INSTALLED:
        age: 1.0.0

Number of packages to be installed: 1

The process will require 6 MiB more space.
1 MiB to be downloaded.

Proceed with this action? [y/N]: y
[1/1] Fetching age-1.0.0.txz: 100%    1 MiB   1.3MB/s    00:01
Checking integrity... done (0 conflicting)
[1/1] Installing age-1.0.0...
[1/1] Extracting age-1.0.0: 100%
$
$ pkg info age  # infoは以下の通り。
age-1.0.0
Name           : age
Version        : 1.0.0
Installed on   : Sat Mar  7 10:37:01 2020 JST
Origin         : security/age
Architecture   : FreeBSD:12:amd64
Prefix         : /usr/local
Categories     : security
Licenses       : BSD3CLAUSE
Maintainer     : dmgk@FreeBSD.org
WWW            : https://github.com/FiloSottile/age
Comment        : Simple, modern and secure file encryption tool
Annotations    :
        FreeBSD_version: 1200086
        repo_type      : binary
        repository     : FreeBSD
Flat size      : 5.87MiB
Description    :
age is a simple, modern and secure encryption tool with small explicit keys, no
config options, and UNIX-style composability.

WWW: https://github.com/FiloSottile/age

$ pkg list age  # インストールされたファイル一覧。manは無い。
/usr/local/bin/age
/usr/local/bin/age-keygen
/usr/local/share/licenses/age-1.0.0/BSD3CLAUSE
/usr/local/share/licenses/age-1.0.0/LICENSE
/usr/local/share/licenses/age-1.0.0/catalog.mk
$

使い方(まずは-hを確認)

実行ファイルはageage-keygenである。
文字通りage-keygenは鍵を作る。
ageが実際の暗号化、復号を受け持つ。

前節で少し書いたけど、manはないので-hを付けて使い方を表示させること。

以下が実行結果であるが、-hを与えたときのage-keygenの素っ気なさとageの熱量の差を感じていただきたい。

$ age-keygen --help  # -hでも--helpでも同じ。
Usage of age-keygen:
  -o FILE
        output to FILE (default stdout)
$
$ age --help
Usage:
    age -r RECIPIENT [-a] [-o OUTPUT] [INPUT]
    age --decrypt [-i KEY] [-o OUTPUT] [INPUT]

Options:
    -o OUTPUT                   Write the result to the file at path OUTPUT.
    -a, --armor                 Encrypt to a PEM encoded format.
    -p, --passphrase            Encrypt with a passphrase.
    -r, --recipient RECIPIENT   Encrypt to the specified RECIPIENT. Can be repeated.
    -d, --decrypt               Decrypt the input to the output.
    -i, --identity KEY          Use the private key file at path KEY. Can be repeated.

INPUT defaults to standard input, and OUTPUT defaults to standard output.

RECIPIENT can be an age public key, as generated by age-keygen, ("age1...")
or an SSH public key ("ssh-ed25519 AAAA...", "ssh-rsa AAAA...").

KEY is a path to a file with age secret keys, one per line
(ignoring "#" prefixed comments and empty lines), or to an SSH key file.
Multiple keys can be provided, and any unused ones will be ignored.

Example:
    $ age-keygen -o key.txt
    Public key: age1ql3z7hjy54pw3hyww5ayyfgxzqgvc7w3j2elw8zmrj2kg5sfn9aqmcac8p
    $ tar cvz ~/data | age -r age1ql3z7hjy54pw3hyww5ayffg7zqgvc7w3j2elw8zmrj2kg5sfn9aqmcac8p > data.tar.gz.age
    $ age -d -i key.txt -o data.tar.gz data.tar.gz.age
$

ご覧の通り、age-keygenで鍵を作り、その鍵を使ってageで暗号化・復号するのが基本だが、ageは単なるコマンドなんで、パイプで繋げられるのがポイント。

実行例

鍵を作る

鍵を作るのはage-keygen
なお、ageでは、ssh鍵も使えるが、それは後ほど。
ともかく、-oに続いて書き出すファイルを指定すれば鍵が書き込まれる。

$ age-keygen -o ~/.config/age/keys.txt
Public key: age1rvvg4xtywl4ceeaqj5auhkg4qjec315ayd24lmath0euzetsfs8czjff
$

鍵を作ると問答無用で公開鍵を表示してくれる。
公開鍵は暗号化するときに使う鍵ですな。
復号するときに使う秘密鍵については、鍵を書き込んだファイルを表示してみると;

$ cat ~/.config/age/keys.txt
# created: 2020-03-07T10:49:42+09:00
# public key: age1rvvg4xtywl0cxeaqj5auhkg4qjec355ayd24lmath0euzetsfs8czjff
AGE-SECRET-KEY-1G9NKY3MA92270K8FWXXXXQQ7ZHPLS3VDTASUGQ9AWG6AD8ZT4SLUM3PM
$

ご覧の通りAGE-SECRET-KEYから続くものが秘密鍵ですな。
なお、鍵の書き込まれたファイルのパーミッションは600で、他人からは見られないようになっている。
秘密鍵だからね。このファイルの管理は厳重に。言わずもがな。

暗号化

基本的な使い方はcatやらしたファイルをパイプで繋ぐ。
以下の例ではplane.txtの内容をageに渡す。
-rで公開鍵を指定。
そのままだと標準出力に暗号化データが吐き出されるので、-oで出力先ファイルを指定。
以下の例だとplane.ageに。

$ cat ./plane.txt
ほげほげ
$ file ./plane.txt
./plane.txt: UTF-8 Unicode text  # UTF-8のプレインテキスト
$
$ cat ./plane.txt |age -o plane.age -r age1rvvg4xtywl0ceeaqj5auhkg4qjec355ayd24lmrth0euzetsfs8czjff

$ file ./plane.age
./plane.age: data  # 出来上がりはバイナリデータの模様
$
$ du -h ./plane*  # やっぱりサイズは増えるよね
4.5K    ./plane.age
512B    ./plane.txt

復号

復号する場合には、--decryptあるいは-dをオプションに与える。
鍵は--identityあるいは-iで指定する。
結果は標準出力に吐き出されるので、必要に応じてファイルにリダイレクトする。

$ age -i ~/.config/age/keys.txt --decrypt ./plane.age
ほげほげ
$
$ age -i ~/.config/age/keys.txt --decrypt ./plane.age > plane.decrypt.txt
$ cat plane.decrypt.txt
ほげほげ
$

暗号化のバリエーション

公開鍵入力のテクニック

いかなageといえど、いちいち公開鍵をコピペするの面倒なので、以下のようにする。

$ cat ./rcpt.txt
age12d2x0gquwpuywl0ceeaqjsXXXXXxvp9j8ae6l04xfh5d85n44qaj8e4r
$ cat ./plane.txt |age -r `cat rcpt.txt`  -o plane.age

複数の宛先へ

暗号化のとき、公開鍵は複数、設定することができる。
この場合、いずれの秘密鍵でも復号できる。
以下の例では、できたファイルはage1AAA, age1BBBの秘密鍵の持ち主それぞれで復号できる

$ cat ./plane.txt |age -r age1AAA.... -r age1BBB...  -o plane.age
$

tarなどのアーカイバと組み合わせる

ディレクトリをtar, gzで固めたものを暗号化
zfsのスナップショットと組み合わせるのもいいね。

$ ls -R ./dir
a.txt   b.txt
 tar cvzf - ./dir |age -r age12d.... -o dir.tgz.age
a ./dir
a ./dir/a.txt
a ./dir/b.txt
$

sshの鍵

sshの公開鍵も使える。

$ cat plane.txt
ほげほげ
$ cat ~/.ssh/id_rsa.pub  # ssh公開鍵
ssh-rsa AAAA(略)
$ cat plane.txt|age -o plane.age -r "`cat ~/.ssh/id_rsa.pub`"  # ダブルクオーテーションで括らないといけないことに注意
$
$ age -d -i ~/.ssh/id_rsa ./plane.age
Enter passphrase for "/home/nobwak/.ssh/id_rsa":  # ssh鍵のパスフレーズ入力
ほげほげ
$

パスフレーズ

-pを与えるとパスフレーズが使える。

$ cat plane.txt
ほげほげ
$ age -p ./plane.txt > plane.age
Enter passphrase:  # パスフレーズを入れる
$
$ age -d ./plane.age  # 復号のときは-dオプション不要
Enter passphrase:
ほげほげ
$