Ubuntu Weekly Recipe

第910回GPGより簡単でZIPより安全⁠シンプルな暗号化ツール「age」試す

機密性のあるファイルを人に渡したい場合や、データベースのバックアップをストレージに保管する場合など、ファイルを暗号化したいシーンは意外と多いものです。今回は簡単に使える暗号化ツールであるageを紹介します。

ファイルの暗号化にまつわる問題

ファイルを暗号化すると聞くと、まずパスワード付きZIPを思い浮かべる人もいるかもしれません。しかし言うまでもなく、パスワード付きZIPは積極的に使いたい方式ではありません。理由は色々ありますが、まず問題なのはパスワードの扱いです。ZIPファイルとパスワードを別のメールで送る、いわゆるPPAPのような運用では、双方が同じ経路で届くため安全性は高くありません。さらにパスワードが短かったり使い回されていたりすると、総当たり攻撃や辞書攻撃にも弱くなるでしょう。もうひとつの問題は、強度の弱い暗号化方式が選択されてしまうケースがあることです。この場合、力技で突破されてしまう可能性も否定できません。

Unixライクな世界では、ファイルの暗号化にはGPGがよく使われてきました。GPGは受信者の公開鍵を使って暗号化するため、PPAPのような問題が起こりません。ところがGPGを使えばすべて解決、というわけでもありません。GPGは非常に高機能ですが、鍵サーバー、キーリングの扱い、キーサイン、失効証明書、信頼度管理など、そのぶん考えなければならないことも多いのです。普段からGPGに慣れ親しんでいる人であればともかく、単純にファイルを暗号化したいという用途では、ここが重荷となることがあります。

そこでもっとシンプルでモダンな、公開鍵暗号による暗号化ツールを使ってみようというのが今回のお話しです。

ageとは

ageはコマンドラインで簡単に使える暗号化ツールです。GitHubのREADMEによると「age is a simple, modern and secure file encryption tool, format, and Go library. It features small explicit keys, post-quantum support, no config options, and UNIX-style composability. ⁠意訳: ageはシンプルでモダンかつ安全なファイル暗号化ツールであり、暗号化ファイルのフォーマットであり、そしてGoライブラリでもあります。 短く明示的な鍵、ポスト量子暗号への対応、設定不要のシンプルな設計、そしてUnixライクのツールらしく、パイプなどで他のコマンドと組み合わせやすいことを特徴としています⁠⁠」とのことです。

ageの最大の特徴は、暗号化ツールとしてのシンプルさです。GPGのようにキーリングや信頼度管理、キーサイン、鍵サーバーなどを含む大きな仕組みではなく、⁠指定した相手の鍵でファイルを暗号化し、対応する秘密鍵で復号する」という用途に絞られています。そのため使い方が分かりやすく、スクリプトにも組み込みやすくなっています。

たとえばバックアップファイルを暗号化して、ファイルサーバーやオブジェクトストレージに保存するといった用途では、サーバー側には暗号化用の公開鍵だけを置き[1]、復号用の秘密鍵は別の安全な場所に保管できます。これによりバックアップ処理を自動化しつつ、サーバーや保存先から平文のデータが漏れるリスクを抑えられます。

ageはパイプ処理との相性もよく、tarなどの既存のコマンドと組み合わせやすい設計になっています。暗号化用の鍵はオプションで明示的に指定する方式のため、コマンドを見ただけで処理内容が見通しやすいのもメリットです。

ただしageは、GPGのすべてを置き換えるツールではありません。例えばageではメール署名などはできません。あくまで「ファイルの暗号化に特化することで、シンプルさと安全性を両立したツール」と考えるとよいでしょう。

ageのインストール

Ubuntuでは、ageはAPTでインストールできます。以下のコマンドを実行してください。

$ sudo apt install -U -y age

鍵ペアの作成

ageで使用する鍵ペアを作成しましょう。age-keygenコマンドを以下のように実行してください。key.txtに秘密鍵が出力され、公開鍵は標準出力に出力されます。

$ age-keygen -o key.txt

Public key: age1...(略)

秘密鍵は復号に使う重要なファイルなので、他のユーザーから読めないようパーミッションを落としておきましょう。

$ chmod 400 key.txt

なお公開鍵は秘密鍵から取り出せます。もし公開鍵を忘れてしまったら「age-keygen -y」コマンドの引数に秘密鍵ファイルを指定して実行してください。

$ age-keygen -y key.txt
age1...(略)

ファイルの暗号化

それでは実際にファイルを暗号化してみましょう。以下はexample.txtというテキストファイルを作り、先ほど作成した公開鍵を使って暗号化するコマンド例です。

$ echo hello > example.txt
$ age -r (暗号化に使うage1ではじまる公開鍵の文字列) -o example.txt.age example.txt

暗号化されたファイルの中身を確認してみましょう。

$ cat example.txt.age 
age-encryption.org/v1
-> X25519 c+Ao+B/qomrlL/IOVelz55toA58Q3YaspSXk1Ep06B0
WL4MmsKAPpD4l/9Px2pe5SPDgzKSRG8wyh9bPksPNWY
--- 2NPY84vaCuSlxHKhWN4U2VklRTOnIiJneSLjSu8QQxg

????p?EXI?m?
            ?ύb????>"i0_??4?j?%   

暗号化されたageファイルは、先頭がテキストのヘッダで、その後に暗号化されたバイナリペイロードが続きます。1行目の「age-encryption.org/v1」は、age v1形式の暗号化ファイルであることを表しています。2〜3行目はrecipient stanza、つまり受信者ごとの情報です。簡単に言えば、このファイルをあるage鍵の持ち主が復号できるようにするための情報が含まれています。⁠---」ではじまる4行目は、ヘッダMACです。その後に続くのがファイル本体を暗号化したバイナリペイロードです。

パイプを経由した暗号化

ageはUnixライクなツールらしく、パイプ処理と非常に相性がよく作られています。標準入力から受け取ったデータを直接暗号化できます。前述の例では、example.txtというテキストファイルを作成してから暗号化していましたが、この処理は以下のように書き換えられます。

$ echo hello | age -r (暗号化に使うage1ではじまる公開鍵の文字列) -o example.txt.age

実際の運用では、ディレクトリをtarでまとめ、そのままageに渡す使い方が便利です。データベースのバックアップ用途などに活用できるでしょう。例えば以下は、/var/lib/dataディレクトリをtarでアーカイブし、backup.tar.ageとして暗号化する例です。

$ tar -C /var/lib/data -cf - . | age -r (暗号化に使うage1ではじまる公開鍵の文字列) -o backup.tar.age

ファイルの復号

暗号化したファイルを復号するには、⁠-d」オプションと、復号に使う秘密鍵を「-i」オプションで指定します。

$ age -d -i key.txt -o example-decrypted.txt example.txt.age

内容を確認してみましょう。

$ cat example-decrypted.txt
hello

なお「-o」オプションを省略すると、復号結果を標準出力に出力します。

$ age -d -i key.txt example.txt.age
hello

パイプを経由した復号

tarでまとめて暗号化したバックアップは、復号しながらそのまま展開できます。前述の通り「age -d」「-o」オプションを省略すると、標準出力へ復号結果を出力するため、これをtarへパイプすることで、復号後のtarファイルを中間ファイルとして保存せずに展開できます。

$ mkdir restore
$ age -d -i key.txt backup.tar.age | tar -C restore -xf -

普段使いのSSH鍵を暗号化に流用する

ageはage-keygenで生成した専用の鍵だけでなく、RSAもしくはEd25519のSSH公開鍵を使っても暗号化できます。なおRSA鍵を使う場合は、2048bit以上の鍵が必要です。たとえば「~/.ssh/id_ed25519.pub」を使って暗号化する場合は以下のようにします。

$ age -R ~/.ssh/id_ed25519.pub -o example.txt.age example.txt

復号時は、対応するSSH秘密鍵を指定します。

$ age -d -i ~/.ssh/id_ed25519 example.txt.age

家庭内サーバーのバックアップなど、復号するのが自分だけという用途では、サーバーごとにage専用の鍵を作るよりも、普段使いのSSH鍵を使い回したほうが鍵管理は楽になるでしょう。他者にファイルを送る場合であっても、公開鍵はGitHubなどから簡単に取得できるため、相手が対応するSSH秘密鍵を手元で使えることが分かっていれば、暗号化したファイルを送る用途でも運用コストを下げられます。

なお公開鍵暗号に詳しい方であれば、署名用のEd25519鍵でなぜ暗号化できるのか疑問に思うかもしれません。実はageはEd25519で直接暗号化しているのではなく、内部でEd25519鍵をX25519鍵に変換し、その鍵を使って復号に必要なファイル鍵を暗号化しています[2]

SSH鍵を使った暗号化は、鍵管理の面ではメリットがありますが、SSH鍵を失うと復号できなくなる点には注意が必要です。特にログイン用のSSH鍵をローテーションしたり、端末の買い替えで鍵を作り直したりする運用をしている場合、古いバックアップを復号できなくなる可能性があります。ageとしても、SSH鍵による暗号化は「オプショナルな便利機能」と位置づけられています。もしもSSH鍵を暗号化に使用するのであれば、秘密鍵はパスフレーズを設定したうえで、安全な場所に保管しておきましょう。やはり長期保存を目的としたバックアップ用途には、age専用の鍵を用いることを推奨します。

おすすめ記事

記事・ニュース一覧