[Linux] ファイルを暗号化する方法あれこれ | A Day In The Boy's Life

A Day In The Boy's Life

とあるエンジニアのとある1日のつぶやき。

Windows上では様々なソフトウェアを通してファイルの暗号化ができますが、Linux上でも様々なコマンドを通して同様にファイルを暗号化しておくことが出来ます。

パスワードが書かれているなど、重要なファイルをサーバー上に置いておき、それに鍵をかけておきたい場合、今回のような暗号化の方法が役に立つと思います。



zipコマンドでファイルにパスワードをかける


こちらはWindowsでもおなじみ方法ですね。

Linux上でも同様にファイルにパスワードをかけ、パスワードがわからないと内容を読み取れないということを設定することが出来ます。

ちなみに、パスワードをかけることができるのはzipコマンドで、gzip(GNU ZIP)そのものでは出来ません。


$ zip -e secret.txt.zip secret.txt
Enter password:
Verify password:
adding: secret.txt (stored 0%)

上記の場合、コマンド実行後にパスワードの入力が求められます。

コマンド内で完結したい場合は、下記のように「-P」オプションを付けてパスワードを指定しておきます。


$ zip -P hogehoge secret.txt.zip secret.txt

$ unzip -P hogehoge secret.txt.zip

圧縮するときと同様に「-P」オプションを付けない場合は、その場でパスワードが求められます。



opensslコマンドを使って共通鍵暗号でファイルを暗号化する


特に圧縮をかけずにファイルを暗号化したい場合、opensslコマンドを通して行うことができます。


$ openssl enc -e -aes256 -in secret.txt -out secret.sec.txt
enter aes-256-cbc encryption password:
Verifying - enter aes-256-cbc encryption password:

上記では、AES暗号 の方式でファイルを暗号化しています。

こちらも暗号化時にパスワード(パスフレーズ)を求められたくなければ、「-k」オプションを付けて実行します。


$ openssl enc -e -aes256 -in secret.txt -out secret.sec.txt -k hogehoge

パスフレーズをコマンドにも入力したくない場合は、パスフレーズを書いたファイルを指定することも出来ます。


$ openssl enc -e -aes256 -in secret.txt -out secret.sec.txt -kfile ./passphrase.txt

復号したい場合は、下記のように「-d」オプション付きで実行します。


$ openssl enc -d -aes256 -in secret.sec.txt -out secret.txt -k hogehoge

opensslコマンドは、暗号化のアルゴリズムを幾つか選べるので適当な暗号化方式を選択し、指定すればよいでしょう。

(それぞれ暗号化の強度が異なってきます)


- Blowfish のアルゴリズムで暗号化する

$ openssl enc -e -bf -in secret.txt -out secret.bf.txt -k hogehoge

異なるアルゴリズムで解凍しようとするともちろんエラーが発生します。


$ openssl enc -d -des3 -in secret.bf.txt -out secret.txt -k hogehoge
bad decrypt
25807:error:06065064:digital envelope routines:EVP_DecryptFinal_ex:bad decrypt:evp_enc.c:325:


opensslコマンドを使って公開鍵暗号でファイルを暗号化する


共通鍵暗号の場合は、パスフレーズがある程度単純になってしまうため、よりセキュリティを意識して暗号化したい場合は、公開鍵暗号を利用する方法もあります。

公開鍵暗号を利用する場合は、まず秘密鍵と公開鍵の2つを作成します。


$ openssl genrsa -out private.key
Generating RSA private key, 512 bit long modulus
..................++++++++++++
..........++++++++++++
e is 65537 (0x10001)

秘密鍵は絶対に外に公開してはならないため、上記の秘密鍵を共通鍵暗号でさらに暗号化しておくという手法もありますが、ここでは割愛します。

次に、上記の秘密鍵のペアとなる公開鍵を作成します。


$ openssl rsa -in private.key -pubout -out public.key

これで2つの鍵のペアが出来ました。

これで、公開鍵で暗号化した情報を秘密鍵によって解読することが出来ます。

公開鍵は、その情報を暗号化したいサーバー上に保存しておきます。

公開鍵と秘密鍵は必ずペアになっているため、秘密鍵から生成した公開鍵の暗号は、元の秘密鍵でしか開くことが出来ません。


次に、公開鍵でファイルを暗号化してみます。


$ openssl rsautl -pubin -inkey public.key -in secret.txt -encrypt -out secret.rsa.txt

上記の暗号化したファイルを秘密鍵で解読してみます。


$ openssl rsautl -inkey private.key -in secret.rsa.txt -decrypt -out secret.txt

鍵ペアさえ作っておけば、コマンドラインで完結することができるので、プログラムから操作する場合でも簡単に使えます。



GNU Privacy Guard(GNU PG)を使ってファイルを暗号化する


gpgというコマンドを通しても公開鍵暗号方式でファイルを暗号化することが出来ます。

GNU PGを使う場合も、まず秘密鍵と公開鍵の2つのペアを作っておきます。


$ gpg --gen-key
gpg (GnuPG) 1.2.1; Copyright (C) 2002 Free Software Foundation, Inc.
This program comes with ABSOLUTELY NO WARRANTY.
This is free software, and you are welcome to redistribute it
under certain conditions. See the file COPYING for details.

すきな鍵の種類を選択してください:
(1) DSAとElGamal (既定)
(2) DSA (署名のみ)
(5) RSA (署名のみ)
どれにしますか? 1
DSA鍵対は1024ビットになります。
新しいELG-E鍵対を生成します。
最小の鍵長は 768 ビット
既定の鍵長は 1024 ビット
最大の推奨鍵長は 2048 ビット
どの鍵長にしますか? (1024) 1024
要求された鍵長は1024ビット
鍵の期限を決めてください。
0 = 無期限
<n> = 有効期限 n 日間
<n>w = 有効期限 n 週間
<n>m = 有効期限 n か月間
<n>y = 有効期限 n 年間
鍵の有効期間は? (0)0
Keyは無期限ですこれでいいですか (y/n)? y

あなたの鍵を同定するためにユーザーIDが必要です。
このソフトは本名、コメント、電子メール・アドレスから
次の書式でユーザーIDを構成します:
"Heinrich Heine (Der Dichter) <heinrichh@duesseldorf.de>"

本名: Foo Bar
電子メール・アドレス: foo.bar@example.com
コメント:
次のユーザーIDを設定しました:
"Foo Bar <foo.bar@example.com>"

名前(N)、コメント(C)、電子メール(E)の変更、またはOK(O)か終了(Q)? o
秘密鍵を保護するためにパスフレーズがいります。

鍵を作成する際に幾つか質問がされますが、上記のようにほとんどデフォルトのもので問題なく作成できます。

メールアドレスやユーザーIDは適当なものを入力します。


この時点で鍵のリストを見てみると


$ gpg --list-key /home/work/.gnupg/pubring.gpg
--------------------------------
pub 1024D/87FDCA4A 2010-03-18 Foo Bar <foo.bar@example.com>
sub 1024g/A4F405D5 2010-03-18

のように秘密鍵が登録されていることがわかります。

次に、さきほど作成した秘密鍵から公開鍵を作成します。


$ gpg -a -o foo_public.key --export foo

次に、公開鍵の信用証明を作成しておきます。

これは、公開鍵が正しいものであるという証明書のようなものです。


$ gpg --export-ownertrust > foo_trust

公開鍵と信用証明が作成できたら、情報を暗号化したいサーバーへ転送しておきます。

サーバー転送したら、そのサーバー上で公開鍵の取り込みを行います。


$ gpg --import foo_public.key
gpg: 鍵87FDCA4A: 公開鍵“Foo Bar <foo.bar@example.com>”を読み込みました
gpg: 処理数の合計: 1
gpg: 読込み: 1

先ほど同様に鍵の一覧を見てみると、公開鍵が取り込まれていることがわかります。


$ gpg --list-key/home/work/.gnupg/pubring.gpg
-----------------------------
pub 1024D/87FDCA4A 2010-03-18
uid Foo Bar <foo.bar@example.com>
sub 1024g/A4F405D5 2010-03-18

次に、上記の公開鍵の信用証明も取り込んでおきます。


$ gpg --import-ownertrust foo_trust
gpg: inserting ownertrust of 6

これで準備が整ったので、ファイルを暗号化してみます。


$ gpg -e -a -r foo.bar@example.com secret.txt
gpg: 信用データベースの検査
gpg: 最小の「ある程度の信用」3、最小の「全面的信用」1、PGP信用モデル
gpg: 深さ: 0 有効性: 1 署名: 0 信用: 0-, 0q, 0n, 0m, 0f, 1u

上記の場合は、コマンド実行後に「secret.txt.asc」というファイルが出来ているかと思います。

これを、秘密鍵をもつサーバーへ転送します。


$ gpg secret.txt.asc
次のユーザーの秘密鍵のロックを解除するには
パスフレーズがいります: "Foo Bar <foo.bar@example.com>"
1024ビットELG-E鍵, ID A4F405D5作成日付は2010-03-18 (主鍵ID 87FDCA4A)
gpg: 1024-ビットELG-E鍵, ID A4F405D5で暗号化2010-03-18にできました "Foo Bar <foo.bar@example.com>"

複合化する際には、秘密鍵を作成した時に入力したパスフレーズが必要です。

パスフレーズが正しければ、ファイルが解読できます。


ちなみに、公開鍵の信用証明をインポートしていなかった場合は、


$ gpg -e -a -r foo.bar@example.com test.txt
gpg: A4F405D5: この鍵が本当に本人のものである、という兆候が、ありません

pub 1024g/A4F405D5 2010-03-18 Foo Bar <foo.bar@example.com>
主鍵の指紋: 2333 136A 3E25 4AA2 5DE6 B905 965B 8128 87FD CA4A
副鍵の指紋: 6FCF F3D8 75ED 6E1A 12BE B6AA EA5D 8E6E A4F4 05D5

この鍵は、このユーザーIDをなのる本人のものかどうか確信でき
ません。今から行うことを*本当に*理解していない場合には、
次の質問にはnoと答えてください。

それでもこの鍵を使いますか? (y/N)

というような注意が表示されます。

もちろん公開鍵が信用できる場合は、特に問題ないでしょうけど毎回質問されるのも面倒ですので、信用証明をインポートしておいた方が良いでしょう。


Linuxにも様々な暗号化の方法がありますので、利用シーンに合わせて使い分けてみてはいかがでしょうか。