Vimとセキュリティ問題

第2回 Vim と暗号化機能

2019.02.01

皆さん御久しぶりです。Vim 使いの「ブイ」(仮名)です。

今回は Vim と暗号化機能について詳しく見ていくことにしましょう。 Vim には暗号化機能がありますが、neovim には実装されていません。それはなぜなのか、Vim の暗号化機能とは一体何なのか追っていくことに意味はあるはずです。

1 Vim の暗号化機能

Vim の暗号化機能とは、独自の暗号化を行ったテキストファイルを読み書きできる機能のことです。このファイルはファイルを暗号化したときに使用したパスワードを知っている人しか開けないので、平文のテキストファイルよりも安全になることが期待できます。

Vim の暗号化を使うには、暗号化したいファイルを開いた後に :X コマンドを実行するのが一番良いです。このコマンドを実行すると暗号化キーを確認のために二回入力する必要があります。一度暗号化を行うと、次に同じファイルを開いたときも暗号化されています。

暗号化したファイルを 16 進ダンプで見てみると、バイナリファイルになっていることが分かります。

$ od -x crypt.txt
000000 56 69 6d 43 72 79 70 74 7e 30 33 21 55 02 32 c3  >VimCrypt~03!U.2.<
        6956  436d  7972  7470  307e  2133  0255  c332
000010 77 7e b1 87 68 51 8b dc df 80 ca 2e 9d 6d 7b 1a  >w~..hQ.......m{.<
        7e77  87b1  5168  dc8b  80df  2eca  6d9d  1a7b
000020 ee 04 6f 61 50                                   >..oaP<
        04ee  616f  0050
000025

もう一つの方法として 'key' オプションで共通の暗号化キーを指定するという方法もありますが、入力をミスするとファイルの内容が消える恐れがあるのであまり推奨されていません。

Vim は外部の暗号化形式を用いずに、独自の暗号化ファイル形式を用いてファイルを暗号化するので、Vim で暗号化したファイルは Vim でしか復号化できないということに注意してください。

暗号化機能を有効にしている場合、スワップファイルも暗号化されるようですが安全性を考えるとスワップファイル機能は無効にするべきです。viminfo には編集中のファイルの情報が一部保存される危険性があるので viminfo も無効にしましょう。アンドゥ情報も無効化するべきです。

それらを考慮し、Vim のドキュメントでは暗号化するファイルを開くときは以下のようにすることが推奨されています。

    :set noundofile viminfo=
    :noswapfile edit secrets.txt

Vim に暗号化機能が実装されたのは、調べてみると Vim 7.0 のころからのようです。 暗号化機能を有効化するには、Vim が暗号化機能 +cryptv を有効にしてビルドされる必要があります。

Vim の暗号化方式は cryptmethod オプションにより決定されます。 Vim 8.1.0606 未満だとデフォルトでは zip というとても弱い暗号化方式が使われてしまうので、暗号化機能を使うなら "blowfish2" を使用するように設定するべきです。

    :set cryptmethod=blowfish2

cryptmethod オプションで使用できる値は以下の通り。

cryptmethod 解説
zip Pkzip 互換の暗号化方式。使用するべきではない。
blowfish blowfish というブロック化暗号方式。Vim 7.3 以上が必要。
脆弱性が報告されている。使用するべきではない。
blowfish2 blowfish というブロック化暗号方式。Vim 7.4.399 以上が必要。
暗号化シードを毎回再生成する。

2 プラグインによる暗号化

これまで Vim 本体の暗号化による説明をしてきましたが、以下の vim-gnupg というVim プラグインを用いてファイルを暗号化することが可能です。

https://github.com/jamessan/vim-gnupg

このプラグインは GnuPG を内部で利用しているために GnuPG の暗号化ファイルを復号化することができ、GnuPG の暗号化 ファイルを作成することも可能です。

セキュリティを担保するために、このプラグインがロードされている場合 viminfo と swapfile は無効化されます。

3 Emacs の暗号化機能

さて、Emacs はどうなのか見ていきましょう。 Emacs だと Emacs 23 より標準となった EasyPG という拡張機能を用いて暗号化・復号化するのが一般的なようです。

この拡張機能は .gpg のファイルを透過的に暗号化・復号化します。つまり、vim-gnupg 相当のものが標準プラグインとしてインストールされていると考えてよいです。

例えば、Emacs 拡張機能の org-mode だと EasyPG の機能を利用してファイルの暗号化をサポートしていたりします。

4 neovim の暗号化に関する議論

さて、それでは本題です。neovim ではなぜ暗号化機能が削除されたのか見ていくことにしましょう。neovim が暗号化機能を削除したのは、以下の issue で提案されたからです。

https://github.com/neovim/neovim/issues/694

該当スレッドはかなり議論が長いのですが、要するに Vim の暗号化機能はちゃんと書かれていないので削除が妥当、本当にこの機能が欲しいならばよりよい実装で再実装するべきだという話です。

確かに暗号化というのはセキュリティを担保する機能なので、きちんと実装するのが難しく、実際に Vim の暗号化機能は過去に脆弱性が報告されています。 本体が独自の実装で暗号化するよりは外部コマンドや外部ライブラリを利用するべきというのは一理あります。外部コマンドやライブラリの場合、それらの開発者は暗号化の専門家だと考えられるし、セキュリティ問題への対処も早いからです。

ちなみに、neovim はただ暗号化機能を削除したわけではなく、よりよい暗号化実装が完成すれば復活させようとしています。

https://github.com/neovim/neovim/issues/701

ただし 2018 年 12 月現在、neovim に新たな暗号化機能を実装しようとする人は現れていません。

5.1 Vim の暗号化に関する議論(blowfish 暗号化方式の脆弱性)

Vim の blowfish 暗号化方式(blowfish2 ではない)に対しては、以下の記事で分析され、「暗号化処理を自作するべきでない」と言われていました。 実際に Vim の blowfish 暗号化ファイルを bruteforce でクラックするコードも紹介されています。

https://dgl.cx/2014/10/vim-blowfish

$ time perl vim-blowfish-bruteforce.pl file
nuclear
unseats
tidings
redeems
markets
toppled
cockier
midyear

perl vim-blowfish-bruteforce.pl file  0.12s user 0.00s system 94% cpu 0.131 total

手元で試してみたところ、0.131 秒で blowfish の暗号化ファイルをクラックできてしまいました。

5.2 Vim の暗号化に関する議論(blowfish2 暗号化方式の問題)

更に、Vim の issues では以下の議論もありました。

https://github.com/vim/vim/issues/638

こちらは、blowfish2 暗号化を使ったとき、ファイルの一部しか入手できなくてもパスワードが当たっていれば入手できたファイルの一部は復号化できるという問題を議論しています。つまり中間者が通信された暗号化ファイルを復号化できるかもしれないということです。認証付き暗号だとこの問題を解決できるので、Issue 作成者は Vim に認証付き暗号の導入を勧めていました。

Vim の blowfish 暗号はブロック長が 64bits しかないのでブロック化暗号としても弱いとの指摘もあります。調べてみたところ、64 bit のブロック長は全数探索に弱いので 128 bit が推奨されるようです。

5.3 Vim の暗号化に関する議論(よりよい暗号化方式の実装について)

以下の issue では Vim が SHA256 ベースの鍵生成方式を用いていることに関しての議論がされています。SHA256 は現代だと GPU を用いて解読可能であるので、bcrypt や scrypt ベースのキー生成のほうが推奨されるようです。

https://github.com/vim/vim/issues/639

Bram 氏はより強い暗号化方式の実装には賛成しているものの、ミスなく実装するのが大変な上に誰からもパッチが送られてこない点に難色を示しています。

libsodium というライブラリは bcrypo, scrypt より新しい Argon2 という鍵生成関数をサポートしており、外部から使用可能な高レベルな関数があるので Vim が内部的に使用するのに向いているのではないかという話があるようです。しかしこちらも特に Vim から使えるようにに対応させたという話は聞きません。

https://github.com/jedisct1/libsodium/

https://github.com/vim/vim/issues/639#issuecomment-200871906

Issue のコメントによると、現在の暗号化アルゴリズムに対する評価は以下の通りのようです。

cryptmethod 解説
zip 脆弱。簡単に復号化できるので使用するべきではない。
blowfish 脆弱。あなたのファイルは部分的に復号化できる。
使用するべきではない。
blowfish2 小さなファイルを暗号化するなら安全。
かなり強いパスワードを用いなければいけない。
他人がファイルに書き込めてはならない。

6 Vim に暗号化機能は必要なのか?

これはあくまで私の予想なのですが Vim が暗号化機能を実装したのは以下のような理由があったのではないでしょうか。

  • blowfish 暗号方式は比較的実装が簡単であった

  • 当時、暗号化のためにライブラリを取りこむことはしたくなかった。もしくは適当な ものがなかった

  • Vim でテキストファイルを簡易的に暗号化できると便利な面があるかもしれないと考 えた

Bram 氏の暗号化関連の issue への返答を見る限り、Bram 氏は暗号化ファイルを同僚や家族に見られない程度の安全性を持っていれば十分だろうという考えのようです。「暗号化ファイルを破られにくい安全な暗号化方式を実装した」わけではないのです。

Vim 7.0 がリリースされたのは 2006 年の 5 月、10 年以上も前の話です。その当時、少しずつセキュリティ問題も認識されつつあったものの、今ほど皆がセキュリティの話題に敏感になってはいませんでした。マシンパワーの限界もありました。

しかし今はもう 2019 年です。マシンパワーが上がり GPU といった効率的な解読方法も生まれ、セキュリティの話題が毎日報道されるような時代です。

もちろん Vim の暗号化も過信せずにうまく使えば便利な場面があるかもしれませんが、Vim の暗号化をよく分かっていない人が重要な情報をこれで保存してしまう危険性はとても無視できるものではありません。

「ザルなセキュリティなら、やらないほうがマシだ」という考えかたがあります。簡単に破られるセキュリティなら、自分は安全だと勘違いする人が出てこないぶんやらないほうがよいのではないかということです。私はこれに賛成です。

例えば以下のように Vim をパスワードマネージャーとして使おうとしたり、クラウドに置く秘密ファイルの暗号化方式として使おうとする人が現れるからです。Vim の暗号化に関する議論を見る限り、現在の Vim の暗号化ファイルをそのような用途に使用するのは危険でしょう。

https://github.com/vim/vim/issues/2566

プラグインによる暗号化については、安全性がそのプラグインがどのような暗号化方式を使っているか、どれくらい気を付けて実装されているかに依存します。 プラグインの実装をよく確認して、「これなら安全だ」と判断できたのなら使用するのも悪くないかもしれません。

This article is made by Vim.

著者プロフィール

v

ブイ。社内では数少ない Vim 使い。ブログ記事の執筆により、社内でのVim の知名度を上げ、Vim を使用する人を増やそうと計画しているらしい。

記事一覧Index