• linux 磁盘加密和tpm搭配使用1


    一.基本名称,容易混淆

    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中管理我们的分区加密密码了。

    水平有限,如果有错误,请帮忙提醒我。如果您觉得本文对您有帮助,可以点击下面的 推荐 支持一下我。版权所有,需要转发请带上本文源地址,博客一直在更新,欢迎 关注 。
  • 相关阅读:
    【Linux】Vim编辑器-批量注释与反注释
    java_部署jar
    linux_UBUNTU 12.04 上使用 SQUID 架设HTTP正向代理服务器
    crawler_java应用集锦9:httpclient4.2.2的几个常用方法,登录之后访问页面问题,下载文件_设置代理
    linux_coom _ Linux文件比较,文本文件的交集、差集与求差
    linux_之sed用法
    算法-跑道与马-百度面试题
    《Python》常用内置模块
    《Python》内置方法进阶和常用模块
    《Python》反射、内置方法(__str__,__repr__)
  • 原文地址:https://www.cnblogs.com/10087622blog/p/7852786.html
Copyright © 2020-2023  润新知