人気ブログランキング |
タグ:暗号化 ( 2 ) タグの人気記事
(Linux)LUKSでファイルシステムを暗号化してみた
さくらのVPS 1G(CentOS6.3 x64) でsambaを使ってファイルサーバを立てようと思ったんですが、重要なデータも置くことがあるため、ファイルシステムレベルで暗号化をして見ることにしました。

さくらのVPSは標準OS(プレインストール)ではパーティションが既にきられているので、一旦カスタムOSで再インストールを行い、暗号化用のパーティションを作成しておきます。(今回使うdm-cryptはブロックデバイスに対して暗号化をかける仕組みなので、暗号化をかけるパーティションを用意する必要有り)

今回は以下の様なパーティションでインストールしました。
(fdisk後継の parted で確認した時のパーティション情報です。パーティションテーブルがGPTなもんで...)

# parted /dev/vda

(parted) print
Model: Virtio Block Device (virtblk)
Disk /dev/vda: 107GB
Sector size (logical/physical): 512B/512B
Partition Table: gpt

Number Start End Size File system Name Flags
1 1049kB 263MB 262MB ext4 Linux filesystem boot ←/boot
2 263MB 2411MB 2147MB linux-swap(v1) Linux swap
3 2411MB 45.4GB 42.9GB ext4  ← /
4 45.4GB 88.3GB 42.9GB ext4  ← /var
5 88.3GB 107GB 19.1GB ext4  ← 暗号化対象パーティション

Linuxの暗号化方式もいくつかあるようですが、今回はカーネルの2.6系列で統合されたdm-cryptを使った暗号化ファイルシステムの標準的な仕様であるLUKSを使うことにしました。
他の暗号化方式としてはループバックデバイス(実装:loop-AES),FUSE(実装:CryptoFS,EncFS)、eCryptfs(実装:eCryptfs)などがあるようです。
このあたりの話はファイルシステムごと暗号化する方法 - SourceForge.JP Magazine : オープンソースの話題満載が参考になります。


LUKSの操作をするには、cryptsetup コマンドを使います。

まず、以下の書式でパーティションを luks で暗号化します。

# cryptsetup luksFormat [-c 暗号化方式] [-s 鍵の長さ] 暗号化対象デバイスファイル

-c、-s指定しないと以下の初期値になります。
暗号化方式:aes-cbc-essiv:sha256
鍵の長さ:256
(128にしようとしたら、以下のエラーでて出来ませんでした。)

device-mapper: reload ioctl on failed: No such file or directory
Failed to setup dm-crypt key mapping for device /dev/vda5.
Check that kernel supports aes-cbc-essiv:sha128 cipher (check syslog for more info).


今回は、以下のようにしました。

# cryptsetup luksFormat -c aes-cbc-essiv:sha256 -s 256 /dev/vda5

WARNING!
========
This will overwrite data on /dev/vda5 irrevocably.

Are you sure? (Type uppercase yes): YES ←大文字で入力すること!
Enter LUKS passphrase: ←暗号化のパスワード入力
Verify passphrase: ←暗号化のパスワードを確認入力


暗号化が完了したら接続してみます。
LUKSパーティションへの接続は、以下のようにします。

# cryptsetup luksOpen デバイス デバイスファイル名(適当な名前)

デバイスファイル名はなんでも構いません。
今回と以下のような感じ。

# cryptsetup luksOpen /dev/vda5 luks
Enter passphrase for /dev/vda5: ←cryptsetup luksFormatに設定したパスワード入力

これで接続完了です。
/dev/mapper/デバイスファイル名 が作成されます。
今回だと、/dev/mapper/luks ですね。

そして、暗号化デバイス上にファイルシステムの作成します。
今回は ext4 にしました。

# mkfs -t ext4 /dev/mapper/luks
mke2fs 1.41.12 (17-May-2010)
Filesystem label=
OS type: Linux
Block size=4096 (log=2)
Fragment size=4096 (log=2)
Stride=0 blocks, Stripe width=0 blocks
1164592 inodes, 4654080 blocks
232704 blocks (5.00%) reserved for the super user
First data block=0
Maximum filesystem blocks=4294967296
143 block groups
32768 blocks per group, 32768 fragments per group
8144 inodes per group
Superblock backups stored on blocks:
32768, 98304, 163840, 229376, 294912, 819200, 884736, 1605632, 2654208,
4096000

Writing inode tables: done
Creating journal (32768 blocks): done
Writing superblocks and filesystem accounting information: done

This filesystem will be automatically checked every 34 mounts or
180 days, whichever comes first. Use tune2fs -c or -i to override.


ファイルシステム作成が終われば、マウントを行います。

# mount /dev/mapper/luks /mnt/secure/

これで使用可能になりました。

今回は初回なのでファイルシステムのフォーマットがありましたが、次から使うときは以下の様な流れになります。

# cryptsetup luksOpen /dev/vda5 luks ←接続
# mount /dev/mapper/luks /mnt/secure/ ←マウント


使い終われば以下のようにパーティションをアンマウントし、暗号化デバイスを削除する必要があります。

# umount /mnt/secure
# cryptsetup luksClose luks

これで、/dev/mapper/luks が削除されます。




OS起動時に自動マウントさせる
いちいち手動で接続、マウントしていると面倒なので、OS起動時に自動マウントさせるようにしました。
そのために、パスワードだけでなくキーファイルで認証できるようにします。(LUKSはキースロットが複数あるので、複数のパスワードやキーファイルが指定できます)


以下のようにキーファイルを作成します。乱数で、1024バイトのファイルを作成してます。

# dd if=/dev/urandom of=/boot/luks_key bs=1 count=1024

(キーファイルは /boot パーティションに配置しておきます。当初別パーティションに分けた /var 配下においてたんですが、自動マウントさせようとするとどうもうまく行かなかったので。。。)
安全のためキーファイルの権限を600か400にします。

# chmod 600 /boot/luks_key

LUKSパーティションにキーファイルの登録します。

# cryptsetup luksAddKey /dev/vda5 /boot/luks_key
Enter any passphrase: ←最初の設定したパスワード入力


以下コマンドでキーファイルが登録されたか確認します。

# cryptsetup luksDump /dev/vda5
LUKS header information for /dev/vda5

Version: 1
Cipher name: aes
Cipher mode: cbc-essiv:sha256
Hash spec: sha1
Payload offset: 4096
MK bits: 256
MK digest: xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx
MK salt: xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx
xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx
MK iterations: 23875
UUID: 5c7a088a-c452-4229-aeb3-c81d15e0e4b5

Key Slot 0: ENABLED ←ここが最初に指定したパスワード認証の設定
Iterations: 95873
Salt: xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx
xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx
Key material offset: 8
AF stripes: 4000
Key Slot 1: ENABLED ←●ENABLEDになっていればkeyfileが登録されている。
Iterations: 128900
Salt: xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx
xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx
Key material offset: 264
AF stripes: 4000
Key Slot 2: DISABLED
Key Slot 3: DISABLED
Key Slot 4: DISABLED
Key Slot 5: DISABLED
Key Slot 6: DISABLED
Key Slot 7: DISABLED


登録したキーファイルでマウントできることを確認します。
(すでにマウントされているなら、アンマウントし暗号化デバイスを削除しておきます)

# cryptsetup luksOpen /dev/vda5 luks --key-file /boot/luks_key
# mount /dev/mapper/luks /mnt/secure/

これでマウントできればキーファイルでの認証OKということになります。


いよいよ暗号化ボリュームを自動でマウントする方法です。
/etc/crypttab に設定を書くことでOS起動時にLUKSへの接続ができるようです。
書式は、以下のようになります。

[cryptsetupデバイス名] [/dev名] [キーファイルへのパス] [LUKS拡張が必要である旨]


今回は以下のようにしてみました。

# vi /etc/crypttab
luks /dev/vda5 /boot/luks_key luks,timeout=5



さて、次はファイルシステムのマウントです。
最初は/etc/fstabで以下のように書いてみました。

# vi /etc/fstab
/dev/mapper/luks /mnt/secure/ ext4 defaults 2 2

しかし、/etc/fstab使ってリブートすると以下のようにエラーになってしまいました。

Mounting local filesystems: mount: special device /dev/mapper/luks does not exist [FAILED]
Enabling local filesystem quotas: [ OK ]
modprobe: FATAL: Error inserting padlock_sha (/lib/modules/2.6.32-279.9.1.el6.x86_64/kernel/drivers/crypto/padlock-sha.ko): No such device

fstabの末尾の数字の設定によっては、起動時に他のパーティションも読み取り専用になってしまうこともあります。
(末尾の数字の意味については@IT:/etc/fstabに記述されている数字の意味を参照)
もしそうなったら "mount -o remount ,rw /" コマンドで書き込み可能でマウントしなおし、/etc/fstab を元に戻します。)


どうも /etc/fstab ではマウントできないようなので(多分、crypttabのマウントの前にfstabのマウントが走るため)、rc.local(システム起動時の最後に読み込まれる)でマウントするようにしました。

# vi /etc/rc.local

mount /dev/mapper/luks /mnt/secure/


リブートしてマウントできてるか確認してみます。

# mount
/dev/vda3 on / type ext4 (rw)
proc on /proc type proc (rw)
sysfs on /sys type sysfs (rw)
devpts on /dev/pts type devpts (rw,gid=5,mode=620)
tmpfs on /dev/shm type tmpfs (rw)
/dev/vda1 on /boot type ext4 (rw)
/dev/vda4 on /var type ext4 (rw)
none on /proc/sys/fs/binfmt_misc type binfmt_misc (rw)
/dev/mapper/luks on /mnt/secure type ext4 (rw)

↑最下行見てみるとちゃんとマウントできてますね。


余談ですが、cryptsetup isLuksコマンドを使うと指定したパーティションがLUKSフォーマットかどうか確認できます。

# cryptsetup isLuks /dev/sdc
# echo $?
0 ←0が表示されればLUKSフォーマットです。



参考:
LUKS - GreenLeaf:
crypttab - GreenLeaf:
Markopee::Notebook: Linux で暗号化ファイルシステムを使う
by Jehoshaphat | 2012-10-22 01:13 | Linux
(.Net)文字列を暗号化する(3DES)
設定ファイルに保存する一部の文字列をちょいと暗号化したかったのでC#でやってみました。
.Netでは共通鍵暗号化方式として3DESが提供されているようで、TripleDESCryptoServiceProviderクラスを使うと簡単にできます。
//鍵
private const string CKEY = "1234567890abcdefghujklm";
//初期化ベクタ
private const string CVEC = "12345678";
 
//暗号化処理
private static string Encript(string str)
{
byte[] src = Encoding.UTF8.GetBytes(str);
//暗号用のキー情報をセットする
byte[] desKey = Encoding.UTF8.GetBytes( CKEY);
byte[] desIV = Encoding.UTF8.GetBytes(CVEC);
//暗号化用の3DESクラス生成
TripleDESCryptoServiceProvider des = new TripleDESCryptoServiceProvider();
MemoryStream ms = new MemoryStream();
//暗号化
CryptoStream cs = new CryptoStream(ms, des.CreateEncryptor(desKey, desIV), CryptoStreamMode.Write);
cs.Write(src, 0, src.Length);
cs.Close();
byte[] cryptData = ms.ToArray();
ms.Close();
 
return Encoding.UTF8.GetString(cryptData);
}
 
//復号化
private static string Decript(string str)
{
//Base64解除
byte[] src = Encoding.UTF8.GetBytes(str);
//暗号用のキー情報をセットする
byte[] desKey = Encoding.UTF8.GetBytes(CKEY);
byte[] desIV = Encoding.UTF8.GetBytes(CVEC);
//復号化用の3DESクラス生成
TripleDESCryptoServiceProvider des = new TripleDESCryptoServiceProvider();
 
MemoryStream ms = new MemoryStream();
//復号化
CryptoStream cs = new CryptoStream(ms, des.CreateDecryptor(desKey, desIV), CryptoStreamMode.Write);
cs.Write(src, 0, src.Length);
cs.Close();
byte[] cryptData = ms.ToArray();
ms.Close();
 
return Encoding.UTF8.GetString(cryptData);
}

鍵の部分で同じ文字列の繰り返しだと、暗号化時に弱すぎるよって例外が発生して怒られました。(具体的に何の例外だったかは忘れましたが。。。)

参考:
GDD Blog: [.NET]文字列の暗号化(3DES)
MSDN:10 行でズバリ !! 暗号化 (C#)
by jehoshaphat | 2010-02-10 00:44 | .Net開発