ふと思い立って、GNU/Linuxでお手軽に使えるCLIのファイル暗号化ツールを探してみた。
評価すべき点は、自由ソフトウェアであることはもちろんとして、主要なディストロでパッケージ化されるほど有名であることと、ファイルの暗号化目的に簡単に使えることだ。「ファイルの暗号化」とは、十分に強い共通鍵暗号で暗号化、復号化することだ。
そして、今回重要視したのは、パスフレーズにUTF-8を使えることだ。パスワードという言い方はあまり好きではない。パスフレーズと呼ぶべきだ。パスフレーズとは、普通の文を使うものである。例えば、
- イスタンブールは昔コンスタンティノープル
- 水平リーベー僕の船そー曲があるシップスクラークか
- 数種類の奇妙な文字で文章を書く、親愛なる日本人の皆さん
などだ。
これらのパスフレーズは人間にとっては作りやすく、覚えやすい。それでいて十分な情報量があり、総当りにも強いので、コンピューターにとっては難しい。従来の、"pa$$w0rd1234"より、はるかに効果的なパスワードの作り方だ。必要なのは単純にある程度の長さだ。ASCIIの大文字小文字数字記号を混ぜるより、十分に長い文を使うべきである。どうせパスフレーズはハッシュ化されて、せいぜい数百ビットの鍵になるのだから。そして、日本人としては、覚えやすいパスフレーズには、当然日本語を使わなければならない。したがって、UTF-8をパスフレーズにできるのは、日本人として必須機能である。人間は、使いにくいツールを使う際には、楽をしようとする。そのため、ASCII文字しか使えないような環境では、"pa$$w0rd#$%^"のような弱いパスワードを使いたくなってしまう。ローマ字は正しい日本語表記の方法ではない。
The GNU Privacy Guard - GnuPG.org
GnuPGはGNUによるOpenPGPの実装である。GPGは、ファイルの共通鍵暗号にも使える。
暗号化
gpg -c --cipher-algo AES256 -o output input
復号化
gpg -d --cipher-algo AES256 -o output input
GnuPGは十分に有名であり、主要なディストロでパッケージ化されている。
問題は使い勝手だ。--cipher-algo AES256などと指定しなければならないのはいかにも面倒だ。設定ファイルを記述することで、デフォルトの暗号アルゴリズムを指定できるが、設定ファイルの書き換えを要するのは、「簡単に使える」とは言わないだろう。
さらに問題なのは、GnuPGはパスフレーズの入力に、エージェントと呼ばれる別のプログラムを使うことだ。多くのディストロのパッケージでは、このエージェントのデフォルトが、GTK+かQtのソフトウェアになっており、結局、パスフレーズの入力にXを使わなければならない。CLIツールなのに勝手にXを使うのは行儀が悪いにもほどがある。ncursesを使ったCLIのエージェントもあるが、デフォルトのエージェントの設定は、設定ファイルを書き換えなければならない。環境変数やオプションで指定する方法もあるらしいが、そのフォーマットが非常に難解でややこしい。一応、GnuPGでは、エージェントを使わない--no-use-agentオプションがある。
Xを利用するエージェントは、あまり出来がよくない。たとえば、ASCII以外の文字を入力できない。これは前述の通り、到底受け入れられない。
GnuPGでは、--no-use-agentを使い、ロケールをUTF-8にし、UTF-8をサポートした端末を使えば、とりあえずUTF-8のパスフレーズを使うことができる。ただし、GnuPG 2では、--no-use-agentは無効化されていて、エージェントが必須になっている。わけがわからない。
それに、GnuPGはあまりにも巨大で、お世辞にもお手軽とは言いづらい。そのファイルフォーマットも複雑だ。
OpenSSL: The Open Source toolkit for SSL/TLS
OpenSSLのCLIツールは、ファイルの共通鍵暗号、復号にも使うことができる。
暗号化
openssl aes-256-cbc -e -salt -in input -out output
復号化
openssl aes-256-cbc -d -in input -out output
もちろんUTF-8も使えるので、日本人でも正しく覚えやすいパスフレーズを使うことができる。
OpenSSLは十分に有名で、主要なディストロでパッケージ化されており、大抵の場合、opensslに依存するソフトウェアがあるので、デフォルトで入っていたりする。
ではお手軽に使えるかというと、そうでもない。たとえば、-saltの指定もそうだが、暗号化方式をオプションで指定しなければならないというのも、使い勝手に悪影響を与える。しかも、aes-256-ecbのような、字面がよく似ているが、使うべきではないような暗号モードも選べてしまう。
ccryptは、AES256をCFBモードで暗号、復号するCLIのソフトウェアである。これ以外の暗号方式はサポートしていないので、わざわざ暗号方式をオプションで指定する必要がない。
ccryptは、暗号と復号を、オプションで指定することもできるし、プログラム名で指定することもできる。
暗号化
ccrypt -e input
もしくは
ccencrypt input
復号化
ccrypt -d input
もしくは
ccdecrypt input
注意すべきこととして、ccryptは入力ファイルを上書きするという事だ。これは、ccryptがあるストレージ上のファイルの暗号化に特化しているための設計だそうだ。つまり、平文を残さないということだ。
ただ、復号化するときにも上書きするというのはどうにも解せない。一応、復号化に関しては、上書きではなく、stdoutに出力する-cオプションと、ccatが存在するので、シェルのリダイレクト機能を利用すれば、復号結果だけは、別のファイルに出力できる。
ccrypt -c -d input > output
暗号化にかんしてはどうしようもない。平文をstdinから読み込む機能もないようだし、自分で書き換えるか、ファイルをコピーするしかないようだ。
また、ファイルを直接上書きするというのは、プロセスやシステムの意図しない停止の際に、ファイルが壊れてしまうおそれがある。そのため、一時ファイルに書き込んでリネームするという-T, --tmpfilesオプションもある。これは、ストレージに平文が残ってしまう恐れもある。
ただ、最近のファイルシステムはジャーナリング機能などもあり、単なるファイルシステム上からのファイルの上書きだけでは不十分だ。本当にストレージ上に平文を残したくなければ、直接ストレージにランダムなビット列を何度も書き込むか、物理的に破壊するべきだろう。いずれにせよ、別のソフトウェアや、ハンマーとかシュレッダーとかを使うべきだ。この仕組みは、どうも現状にそぐわないように思われる。
追記:そもそも、ディスク全体を暗号化しておくべきじゃないのか。