ファイルをお手軽に暗号化したい! – openssl cms のススメ
2021年03月18日 木曜日
CONTENTS
はじめに
今回は、IIJ Engineers Blog編集部より、IIJ社内の雰囲気が少し垣間見えるような記事をお送りします。
IIJの社内掲示板では、エンジニアのちょっとした技術ネタが好評となって多くのコメントが付いたり、お役立ち情報が掲載されています。
そんな書き込みを眺めては、
「社内だけに留めておくのはもったいない。きっとこういった情報を欲している人もいるはず!」
と思い、編集部が社内掲示板からチョイスしたものを記事にしてみました。
今回紹介するのは「手軽にファイルを暗号化 - openssl cms」
手軽にファイルを暗号化する手法のひとつとして openssl cms を紹介します。
どうぞご覧ください!
みなさん、機密情報を USB メモリを介して受け渡したり、ネットワークを介してコピーしたいとき、どうやって暗号化していますか?
“gpg” を思い付いたあなた。エントロピーが足りないとかいってダンマリを決められたり、気がついたら gpg-agent などという謎のデーモンが勝手に動き出していたり、やたら冗長なくせに間違いやすいコマンドラインオプションに悩まされたり、これだから G 製ツールは、などと思っていませんか?
“openssl enc” と答えたあなた。opensslはその辺りにあるホストにもだいたいインストールされているので、良いチョイスだと思います。しかし、受け渡し相手がいまだにレガシーな openssl 1.0.2 を使っていて渡した後にほどけない!と言われ溜息をついたことはありませんか?
(openssl encで使われるダイジェスト関数のデフォルトはopenssl 1.0.2まではmd5でしたが、openssl 1.1.0以降はsha256に変更されており、デフォルトの挙動に互換性がありません)
https://www.openssl.org/news/changelog.html#openssl-102
Changed default digest for the dgst and enc commands from MD5 to sha256
そんなあなたに CMS です。”openssl cms” でさくっと暗号メッセージが作れます。しかも公開鍵暗号が使えます。共通鍵をどう教えようかと頭を悩ます必要もありませんね。
openssl enc | openssl cms | |
---|---|---|
用途 | ファイル・データの暗号化・復号 | S/MIME 3.1に準拠したメッセージの暗号化・復号・署名・署名検証 |
準拠規格 | RFC3852 Cryptographic Message Syntax (CMS) | |
暗号鍵 | 共通鍵方式 | 公開鍵方式 |
登場 | openssl 0.9.x から存在 | openssl 1.0.0 |
注意 | openssl 1.1.0以降でデフォルト挙動が変更 |
1. 公開鍵を作る
% openssl genrsa -out key.pem 4096 % openssl req -new -x509 -key key.pem -out cert.pem -subj /CN=foo
まずは鍵の生成です。受け取り側のホストでさくっと公開鍵の鍵ペアを作りましょう。CMS は X.509 証明書を使うので、いつもの手順で自己署名証明書を作ってください。できたら送り側ホストに公開鍵 cert.pem をコピってください。PEM はテキストなのでコピぺでも OK です。秘密鍵 key.pem の安全性が気になる人は genrsa に -aes256 をつけて暗号化するなりしてください。
2. 暗号化する
% openssl cms -aes256 -binary -encrypt -in naisyo.txt -out naisyo.txt.enc cert.pem
それでは naisyo.txt を暗号化しましょう。これで naisyo.txt が暗号化されて naisyo.txt.enc ができました。簡単ですね。例では .txt ですが、”-binary” をつけているのでバイナリファイルも OK です。
3. 復号する
% openssl cms -decrypt -in naisyo.txt.enc -out naisyo.txt -inkey key.pem
naisyo.txt.enc を受け取り側のホストに持ってきたら、秘密鍵を使って復号します。これだけです。なんて簡単。あとは使い終わった {cert,key}.pem を消してしまえば安心です。
というわけで、openssl cms による機密情報の暗号化の紹介でした。unix 系ホストで使えるお手軽な暗号化ツールとしては割といけてるんじゃないでしょうか?
Mac は openssl ではなく libressl のため使えないようです。
投稿者いわく「LibreSSL の 2.5.0 で CMS が削られて、3.1.0 で復活していました。そして macOS Big Sur の LibreSSL は 2.8.3 で CMS が削られていた期間のものなので使えない、と。うーん、残念です。どこでも使える暗号化ってなかなか無いものですね。」とお悩みのご様子。
おわりに
いかがでしたでしょうか。
すべての環境に適さないものの、環境が揃いさえすれば手軽に暗号化できると思います。
みなさんもぜひ試してみてください。
追記 (2021年3月25日)
上記の注記の通り、macOS Big Surに収録されたLibreSSLはたまたまcmsコマンドが削除されていた時期のもので、記事本文で紹介した方法が使えませんでした。(実は、この件も社内掲示板に寄せられたコメントから発覚しています)
その後、元記事の著者が改めてLibreSSLのmanを読み解き、さらに互換性の高い方法を発見して社内掲示板に追加記事を投稿してくれました。以下に転載して紹介します。
ファイルの暗号化ならopenssl smimeだ!
macOS 等の古めの LibreSSL が入っている環境で openssl cms が使えないことを教えてもらって、そしてまさに自分が使おうとしていた環境でも古い LibreSSL が入っている可能性があるらしいことを知って、代替策を探していました。LibreSSL のながーい openssl(1) をながめていたら、都合の良いものがありました。”openssl smime” です。そう、openssl(1) は S/MIME のテキストを操作できるのです。しかも使い勝手も openssl cms とだいたい同じです (というか cms の方が smime に似せて作られたんでしょうね)。
openssl smime の使い方:
1. 公開鍵を作る
% openssl genrsa -out key.pem 4096 % openssl req -new -x509 -key key.pem -out cert.pem -days 3650 -subj /CN=`hostname`
鍵ペアを証明書のかたちで作るところまでは同じです。openssl req で “Can’t load …/.rnd into RNG” などと文句を言われたら、openssl rand -writerand $HOME/.rnd で種を作っておいてください。有効期限は -days 3650 で約十年にしています。
2. 暗号化する
% openssl smime -aes256 -binary -encrypt -in naisyo.txt -out naisyo.txt.enc cert.pem
前回の openssl cms との違いは二つ目のサブコマンド名だけです。シンプル。
3. 復号する
% openssl smime -decrypt -in naisyo.txt.enc -out naisyo.txt -inkey key.pem
復号も同じです。openssl smime で作られた暗号文はメールメッセージの一部にも見えるので、勘違いされたくない場合は暗号化時に -outform pem を、復号時に -inform pem をつけてやると PKCS7 の PEM 形式になってなんとなくそれっぽく見えて良いかもしれません。