一.基本名稱,容易混淆
1.dm-crypt是linux的2.6內核開始集成的一種磁盤加密功能。十幾年來,連sche調度算法都被改了N次,但dm-crypt一直穩定在內核中,穩定性還是很好的。
2.cryptsetup是linux一般自帶的一個用戶態工具,用來操作dm-crypt。
[root@localhost mnt]# whereis cryptsetup cryptsetup: /usr/sbin/cryptsetup /usr/share/man/man8/cryptsetup.8.gz
3.luks是dm-crypt 最常用的一種模式,因為是linux中最常用的,所以有人經常混淆這三個東西。
二.dm-crypt支持的類型
open <device> <name> --type <device_type> Opens (creates a mapping with) <name> backed by device <device>. Device type can be plain, luks (default), loopaes or tcrypt. For backward compatibility there are open command aliases: create (argument-order <name> <device>): open --type plain plainOpen: open --type plain luksOpen: open --type luks loopaesOpen: open --type loopaes tcryptOpen: open --type tcrypt-------這個在cryptsetup 的1.6版本之后才開始支持。
四種模型,建議使用luks。
PLAIN DM-CRYPT OR LUKS? Unless you understand the cryptographic background well, use LUKS. With plain dm-crypt there are a number of possible user errors that massively decrease security. While LUKS cannot fix them all, it can lessen the impact for many of them.
由於cryptsetup 也在不停發展,在1.6的版本之后才開始支持tcrypt,所以如果要測試tcrypt 模式,建議使用高版本的內核,這樣自帶的cryptsetup 一般都支持。
# cryptsetup --version cryptsetup 1.6.7
三.測試記錄:
由於不同的模式有不同的參數,本文記錄的是luks模式。
You can only call luksFormat on a LUKS device that is not mapped. <options> can be [--hash, --cipher, --verify-passphrase, --key-size, --key-slot, --key-file (takes precedence over optional second argument), --keyfile-offset, --keyfile-size, --use-random | --use-urandom, --uuid, --master-key-file, --iter-time, --header, --force-password]. WARNING: Doing a luksFormat on an existing LUKS container will make all data the old container permanently irretrievable, unless you have a header backup.
怎么設置參數呢?如果沒指定的話,cryptsetup 會使用默認參數。
先fdisk分配一個分區,本文例子中,分區是sdb2。
對比兩次不同的算法搭配不同的模式的性能比較:
[root@localhost mnt]# cryptsetup benchmark # Tests are approximate using memory only (no storage IO). PBKDF2-sha1 583839 iterations per second PBKDF2-sha256 361577 iterations per second PBKDF2-sha512 231985 iterations per second PBKDF2-ripemd160 464794 iterations per second PBKDF2-whirlpool 234475 iterations per second # Algorithm | Key | Encryption | Decryption aes-cbc 128b 646.6 MiB/s 2649.2 MiB/s serpent-cbc 128b 79.2 MiB/s 535.7 MiB/s twofish-cbc 128b 170.5 MiB/s 352.5 MiB/s aes-cbc 256b 478.4 MiB/s 2049.6 MiB/s serpent-cbc 256b 90.6 MiB/s 553.2 MiB/s twofish-cbc 256b 183.2 MiB/s 353.4 MiB/s aes-xts 256b 2238.0 MiB/s 2244.4 MiB/s serpent-xts 256b 551.2 MiB/s 533.5 MiB/s twofish-xts 256b 342.4 MiB/s 349.7 MiB/s aes-xts 512b 1771.8 MiB/s 1767.3 MiB/s serpent-xts 512b 552.3 MiB/s 535.4 MiB/s twofish-xts 512b 343.8 MiB/s 349.3 MiB/s [root@localhost mnt]# cryptsetup benchmark # Tests are approximate using memory only (no storage IO). PBKDF2-sha1 585142 iterations per second PBKDF2-sha256 353293 iterations per second PBKDF2-sha512 233224 iterations per second PBKDF2-ripemd160 463151 iterations per second PBKDF2-whirlpool 235741 iterations per second # Algorithm | Key | Encryption | Decryption aes-cbc 128b 646.2 MiB/s 2622.6 MiB/s serpent-cbc 128b 90.5 MiB/s 551.6 MiB/s twofish-cbc 128b 183.8 MiB/s 353.0 MiB/s aes-cbc 256b 479.0 MiB/s 2048.1 MiB/s serpent-cbc 256b 90.4 MiB/s 554.1 MiB/s twofish-cbc 256b 183.6 MiB/s 353.5 MiB/s aes-xts 256b 2237.1 MiB/s 2238.7 MiB/s serpent-xts 256b 554.0 MiB/s 534.2 MiB/s twofish-xts 256b 339.8 MiB/s 348.9 MiB/s aes-xts 512b 1773.2 MiB/s 1708.6 MiB/s serpent-xts 512b 553.3 MiB/s 535.7 MiB/s twofish-xts 512b 343.6 MiB/s 348.2 MiB/s
可以看到,aes搭配xts性能較高,所以我們創建加密分區的時候,使用這種模式。
cryptsetup --cipher aes-xts-plain64 --key-size 512 --hash sha512 luksFormat /dev/sdb2
這個表示加密方式是aes-xts-plain64,密鑰長度為512,散列算法為sha512 。
[root@localhost mnt]# cryptsetup --cipher aes-xts-plain64 --key-size 512 --hash sha512 luksFormat /dev/sdb2 WARNING! ======== This will overwrite data on /dev/sdb2 irrevocably. Are you sure? (Type uppercase yes): YES Enter passphrase: Verify passphrase:
密碼必須大於8位,且不能是簡單密碼,否則會無法通過。
用 LUKS 方式創建(格式化)加密盤之后,開始可以打開該盤用於操作了。
cryptsetup open /dev/sdb2 caq_Encrypted_Fs Enter passphrase for /dev/sdb2:
輸入之前的密碼,open成功,由於默認的open格式是luks,所以不需要輸入對應的格式。否則,需要按照下面的格式來。
Opens (creates a mapping with) <name> backed by device <device>. Device type can be plain, luks (default), loopaes or tcrypt. For backward compatibility there are open command aliases: create (argument-order <name> <device>): open --type plain plainOpen: open --type plain luksOpen: open --type luks loopaesOpen: open --type loopaes tcryptOpen: open --type tcrypt
可以看到,在/dev/mapper下,有一個創建的虛擬設備了。
[root@localhost mnt]# ls /dev/mapper/caq_Encrypted_Fs /dev/mapper/caq_Encrypted_Fs [root@localhost mnt]# cryptsetup status /dev/mapper/caq_Encrypted_Fs /dev/mapper/caq_Encrypted_Fs is active. type: LUKS1 cipher: aes-xts-plain64 keysize: 512 bits device: /dev/sdb2 offset: 4096 sectors size: 815104 sectors mode: read/write
之后,我們所有的操作都是基於caq_Encrypted_Fs。比如掛載,讀寫等。
創建一個目錄,用來掛載。
mkdir -p /mnt/caqEncryptedFilesystem/
然后對我們的盤進行建立文件系統的操作:
root@localhost mnt]# mkfs.xfs -b size=4096 -d sunit=0,swidth=0 /dev/mapper/caq_Encrypted_Fs meta-data=/dev/mapper/caq_Encrypted_Fs isize=512 agcount=4, agsize=25472 blks = sectsz=4096 attr=2, projid32bit=1 = crc=1 finobt=0, sparse=0 data = bsize=4096 blocks=101888, imaxpct=25 = sunit=0 swidth=0 blks naming =version 2 bsize=4096 ascii-ci=0 ftype=1 log =internal log bsize=4096 blocks=1605, version=2 = sectsz=4096 sunit=1 blks, lazy-count=1 realtime =none extsz=4096 blocks=0, rtextents=0 [root@localhost mnt]# mount /dev/mapper/caq_Encrypted_Fs /mnt/caqEncryptedFilesystem/
掛載之后,可以對/mnt/caqEncryptedFilesystem/ 進行正常的文件讀寫了。
[root@localhost mnt]# cd /mnt/caqEncryptedFilesystem/ [root@localhost caqEncryptedFilesystem]# ls [root@localhost caqEncryptedFilesystem]# [root@localhost caqEncryptedFilesystem]# [root@localhost caqEncryptedFilesystem]# dd if=/dev/zero of=caq.txt bs=4K count=10 10+0 records in 10+0 records out 40960 bytes (41 kB) copied, 0.000195657 s, 209 MB/s [root@localhost caqEncryptedFilesystem]# ls * caq.txt [root@localhost caqEncryptedFilesystem]# echo "do it yourself" >>caq.txt2 [root@localhost caqEncryptedFilesystem]# ls caq.txt caq.txt2
加密,顧名思義,保存在硬盤上的數據,應該就不是明文了,但是我們cat 看到的文件和寫的文件是一樣的,是因為經過了解密。如果硬盤丟失了,就不會有各種艷照門出現了。
描述到此,也沒看出分區加密和tpm什么關系啊,下面,開始描述兩者結合產生的效果。
我們知道,tpm能夠加密文件,如果我們的加密分區的密碼是以文件的形式存在,兩者就很好地配合了。來看下面的操作:
先產生一個隨機文件:
dd if=/dev/urandom of=/tmp/passwd_caq bs=1k count=64
我們看dump默認的輸出,是密碼數組,所謂密碼數組,是指可以用一組獨立的密碼來解密這個加密的分區。
# cryptsetup luksDump /dev/sdb2 LUKS header information for /dev/sdb2 Version: 1 Cipher name: aes Cipher mode: xts-plain64 Hash spec: sha512 Payload offset: 4096 MK bits: 512 MK digest: e6 12 5c 12 e8 ab 1d 8a 81 ac cc f6 e5 7d bb d0 e2 6c 5f ed MK salt: a8 03 1d b6 05 c8 64 cb de f4 2a 64 0d 77 5b cb b9 11 aa e7 d2 58 eb aa aa 68 24 8f bf 16 26 f2 MK iterations: 28000 UUID: da24c447-4e62-463b-b533-89bd7fdf3238 Key Slot 0: ENABLED Iterations: 112280 Salt: 10 8f 31 ab 38 9a e1 28 94 df 61 0b 43 62 5e 94 57 0c c7 18 fc e8 d6 39 e7 5d d1 93 76 0e f1 13 Key material offset: 8 AF stripes: 4000 Key Slot 1: DISABLED 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 luksAddKey /dev/sdb2 /tmp/passwd_caq
Enter any passphrase:
現在,/tmp/passwd_caq 就成為了這個加密分區的密碼文件了。重新dump一下,發現用掉了一個組,還剩下6個。
# cryptsetup luksDump /dev/sdb2 LUKS header information for /dev/sdb2 Version: 1 Cipher name: aes Cipher mode: xts-plain64 Hash spec: sha512 Payload offset: 4096 MK bits: 512 MK digest: e6 12 5c 12 e8 ab 1d 8a 81 ac cc f6 e5 7d bb d0 e2 6c 5f ed MK salt: a8 03 1d b6 05 c8 64 cb de f4 2a 64 0d 77 5b cb b9 11 aa e7 d2 58 eb aa aa 68 24 8f bf 16 26 f2 MK iterations: 28000 UUID: da24c447-4e62-463b-b533-89bd7fdf3238 Key Slot 0: ENABLED Iterations: 112280 Salt: 10 8f 31 ab 38 9a e1 28 94 df 61 0b 43 62 5e 94 57 0c c7 18 fc e8 d6 39 e7 5d d1 93 76 0e f1 13 Key material offset: 8 AF stripes: 4000 Key Slot 1: ENABLED Iterations: 110917 Salt: 91 18 c0 0c 4d 19 c2 96 85 d1 b6 4a a6 6d 8e 90 d3 96 5f d0 d4 78 28 a3 27 4d 4d ad 94 74 98 28 Key material offset: 512 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
然后我們umount這個掛載的路徑,看新增加的密碼文件能否解密我們的分區。
[root@localhost mnt]# umount /mnt/caqEncryptedFilesystem/ [root@localhost mnt]# cryptsetup close /dev/mapper/caq_Encrypted_Fs
[root@localhost mnt]# cryptsetup --key-file /tmp/passwd_caq luksOpen /dev/sdb2 caq_Encrypted_Fs
從第三行可以看出,再也不用輸入密碼了,直接從文件中讀密碼。
下面的步驟,就簡單了,使用之前的一篇博客,《linux tpm 測試完整記錄,親測有效》來再次加密這個/tmp/passwd_caq,就可以統一在tpm中管理我們的分區加密密碼了。