Total Pageviews

Wednesday, 18 July 2018

磁盘加密工具-Cryptsetup

Cryptsetup is a utility used to conveniently setup disk encryption based on DMCrypt kernel module.
These include plain dm-crypt volumes, LUKS volumes, loop-AES and TrueCrypt (including VeraCrypt extension) format.
Project also includes veritysetup utility used to conveniently setup DMVerity block integrity checking kernel module and, since version 2.0, integritysetup to setup DMIntegrity block integrity kernel module.

LUKS Design

LUKS is the standard for Linux hard disk encryption. By providing a standard on-disk-format, it does not
only facilitate compatibility among distributions, but also provides secure management of multiple user passwords.
In contrast to existing solution, LUKS stores all setup necessary setup information in the partition header,
enabling the user to transport or migrate his data seamlessly.
Last version of the LUKS format specification is available here.

Why LUKS?

  • compatibility via standardization,
  • secure against low entropy attacks,
  • support for multiple keys,
  • effective passphrase revocation,
  • free.

Project home page.

Frequently asked questions (FAQ)

Download

All release tarballs and release notes are hosted on kernel.org.
The latest cryptsetup version is 2.0.3
Previous versions

Source and API docs

For development version code, please refer to source page, mirror on kernel.org or GitHub.
For libcryptsetup documentation see libcryptsetup API page.
The libcryptsetup API/ABI changes are tracked in compatibility report.
NLS PO files are maintained by TranslationProject.

Help!

Please always read FAQ first. For cryptsetup and LUKS related questions, please use the dm-crypt mailing list, dm-crypt@saout.de.
If you want to subscribe just send an empty mail to dm-crypt-subscribe@saout.de.
You can also browse list archive or read it through web interface.

from https://gitlab.com/cryptsetup/cryptsetup
-----

Linux下分区加密LUKS



Linux内核自带的磁盘分区加密,与Android的dm-crypt同样方便。
编程随想曾经介绍过LUKS和VeraCrypt,博主把两者都测试了一下,写下LUKS的使用方法。

创建

假设要在/dev/sda2上进行创建,创建过程会格式化该分区。验证密码的方式常用有两种:密码和key-file

使用密码创建

sudo cryptsetup luksFormat /dev/sda2
创建过程输入大写YES确认格式化分区,然后输入密码。

使用key-file创建

生成一个随机数二进制文件(熵较大的随机数适合做key-file,普通文本熵较小,因此比纯密码要安全)
以生成一个64K的文件(/tmp/MyKey.bin)为例,为安全起见不要小于1KB。妥善保管,丢后无法打开加密分区。
dd if=/dev/urandom of=/tmp/MyKey.bin bs=1k count=64
创建LUKS分区,此时指定Key-file
sudo cryptsetup --key-file /tmp/MyKey.bin luksFormat /dev/sda2

挂载、卸载分区

创建后,挂载加密分区
# 密码
sudo cryptsetup luksOpen /dev/sda2 xxx

# key-file
sudo cryptsetup luksOpen /dev/sda2 --key-file /tmp/MyKey.bin xxx
xxx为/dev/mapper下将要创建的文件名,可以随意设置。当解密成功后可以直接操作/dev/mapper/xxx这个块设备,而不是操作/dev/sda2。
实际上系统会自动创建软链接到/dev/dm-yyy(yyy是数字),指向/dev/mapper/xxx这个块设备(。
若第一次挂载前,需要格式化这个分区,设置卷标(可选操作)
sudo mkfs.ext4 /dev/mapper/xxx
sudo e2label /dev/mapper/xxx "my-private"
挂载该分区
mkdir /tmp/my-priavte
sudo mount /dev/mapper/xxx /tmp/my-priavte
若第一次挂载,记得设置恰当的访问权限,否则没权限读写啊
sudo chown username:username -R /tmp/my-priavte
使用完毕后,卸载分区
sudo umount /tmp/my-priavte
sudo cryptsetup luksClose /dev/mapper/xxx
实测Kubuntu 18.04支持直接从资源管理器输入密码挂载加密分区。
也可以自己指定在/etc/fstab挂载已解密的分区,不过要指定noauto方式,最终还是得手动挂载
# 记下/dev/mapper/xxx的 UUID
sudo blkid
/dev/mapper/luks-0dee9fef-33c4-423e-9d4b-d39c8bd5adac: LABEL="hello" UUID="7455aa01-e36f-4771-9f9b-723d786416ec" TYPE="ext4"

# vi /etc/fstab增加一行
UUID=7455aa01-e36f-4771-9f9b-723d786416ec /tmp/hello ext4 defaults,noauto 0 2

增加、删除、修改slot

LUKS具备8个slot,每个slot可以设置密码或者key-file验证。这8个slot目的就是加密master-key。
格式化后的分区只有一个slot。
每个“Key Slot”好比是一个独立的钥匙:都可以用来打开这个加密盘。
查看当前的slot状态 显示Disabled就是尚未使用的slot
sudo cryptsetup luksDump /dev/sda2
增加slot:密码或者key-file,增加时候需要验证已有的slot
# 密码方式
sudo cryptsetup luksAddKey

# key-file方式,创建一个新keyfile
dd if=/dev/urandom of=/tmp/MyAnotherKey.bin bs=1k count=64
# 法1: 验证原有的keyfile,再添加另一个keyfile
sudo cryptsetup luksAddKey /tmp/MyAnotherKey.bin --key-file /tmp/MyKey.bin
# 法2: 验证原有密码,再添加另一个keyfile
sudo cryptsetup luksAddKey /tmp/MyAnotherKey.bin
删除slot的方法一:通过slot号码删除
# 先记下slot的号码(0~7),比如1
sudo cryptsetup luksKillSlot /dev/sda2 1
删除slot的方法二:通过输入一个有效的slot验证删除
# 输入有效密码
sudo cryptsetup luksRemoveKey /dev/sda2

# 删除一个key-file对应的slot
sudo cryptsetup luksRemoveKey /dev/sda2 --key-file /tmp/MyAnotherKey.bin
若要删除所有slots(不需要验证密码,不可逆的毁灭性操作,只能通过恢复已备份的header来拯救)
sudo cryptsetup luksErase
修改slot,以下方法都可以
# 验证原有密码,修改密码
sudo cryptsetup luksChangeKey /dev/sda2
#  验证原有密码,修改成另一个keyfile
sudo cryptsetup luksChangeKey /dev/sda2 /tmp/MyAnotherKey.bin
# 验证原有的keyfile,修改成新密码
sudo cryptsetup luksChangeKey /dev/sda2 --key-file /tmp/MyKey.bin
# 验证原有的keyfile,修改成另一个keyfile
sudo cryptsetup luksChangeKey /dev/sda2 /tmp/MyAnotherKey.bin --key-file /tmp/MyKey.bin

备份、恢复、擦除Header

man手册中有这么一段话
If the header of a LUKS volume gets damaged, all data is permanently lost unless you have a header-backup. If a key-slot is damaged, it can only be restored from a header-backup or if another active key-slot with known passphrase is undamaged.
上面的意思:如果LUKS的Header被破坏了,数据将永远丢失。如果Slot被破坏了则只能从header备份恢复。要么使用一个没有被破坏的slot。

备份header

sudo cryptsetup luksHeaderBackup /dev/sda2 --header-backup-file /tmp/header.bin
header属于机密信息,确保不让别人发现你的header。如果你擦除了header,而别人使用你的header恢复了header,那么你的擦除将是徒劳。

恢复header

sudo cryptsetup luksHeaderRestore /dev/sda2 --header-backup-file /tmp/header.bin
恢复后,所有slot将被重置为/tmp/header.bin的内容

擦除header

Damaging the LUKS header is something people manage to do with surprising frequency. This risk is the result of a trade-off between security and safety, as LUKS is designed for fast and secure wiping by just overwriting header and key-slot area.
上面的意思:有些人会将header毁灭,用于将数据无法恢复,LUKS则出于性能和简单的设计,毁灭的操作是直接覆盖header数据。
擦除前,从header可以判断这是一个Luks分区
sudo cryptsetup -v isLuks /dev/sdb2 # Command successful.
擦除头部1052672个字节(默认的header大小,仅包含1个slot,实际情况是slot越多,header尺寸越大)
head -c 1052672 /dev/zero > /dev/sda2
sync
那么除了头部1052672字节,后面都是原来加密的数据,只是这个header被我们手工破坏了。再次验证这个分区是否为有效的LUKS分区
sudo cryptsetup -v isLuks /dev/sdb2 # Command successful. # is not a valid LUKS device

备份MasterKey

设计8个slot的目的只有一个:解密master-key,因此master-key才是最重要的。一旦master-key泄漏,什么slot验证都是虚设,能直接被解密数据。
Beware that the master key cannot be changed without reencryption and can be used to decrypt the data stored in the LUKS container without a passphrase and even without the LUKS header. This means that if the master key is compromised, the whole device has to be erased to prevent further access. Use this option carefully.
上面这段话凸显了MasterKey比Header更重要,因为直接绕过了slot验证。一旦masterKey落入他人手中,你只能擦除整个分区来避免他读取机密数据。
下面这个命令可以导出MasterKey,输入大写YES确定。
# 密码验证
sudo cryptsetup luksDump --dump-master-key /dev/sda2

# key-file验证
sudo cryptsetup luksDump --dump-master-key /dev/sda2 --key-file /tmp/MyKey.bin
dump的时候,无论是通过哪个slot验证,输出的master key都是同一个。
将MK dump内容字节串:复制好
89 53 d5 3e a0 4a 80 ea a3 ec 69 fc f0 6d ff 22 
1f 3e df 2b 1a c2 05 6e bf 2d f1 61 39 dd 77 5e
创建为一个dumpInput.txt纯文本,粘贴字节串,然后xxd命令转成master-key二进制文件
xxd -r -p dumpInput.txt /tmp/master-key.bin
使用master-key直接打开加密盘,无需验证slot:
sudo cryptsetup luksOpen --master-key-file /tmp/master-key.bin
知道这玩意的可怕了吗?Master Key更需要妥善保管!!

参考链接

编程随想:扫盲 dm-crypt——多功能 Linux 磁盘加密工具
10 Linux cryptsetup Examples for LUKS Key Management
LUKS: Add a Backup Key, Backup, Restore and Delete LUKS Volume Header
-------

保护数据,用 LUKS 给磁盘全盘加密

最近入手了块新的移动硬盘用于备份数据,到手之后第一件事情是对硬盘进行加密,之前经常使用的 VeraCrypt,由于这块硬盘不需要在其他平台上使用,所以这次打算换点玩法,充分利用上系统自带的 LUKS,来完成对设备的加密。

LUKS is the standard for Linux hard disk encryption. By providing a standard on-disk-format, it does not only facilitate compatibility among distributions, but also provides secure management of multiple user passwords. In contrast to existing solution, LUKS stores all setup necessary setup information in the partition header, enabling the user to transport or migrate his data seamlessly.

便于理解起见,整个流程为:

  1. 准备硬盘(插上电脑)
  2. 直接把整块硬盘创建为一个加密的块设备
  3. 解密创建好的块设备并且 map 到系统上(此时把 map 出来的设备作为一个物理设备看待)
  4. 给 map 出来的设备创建文件系统
  5. 挂载那个文件系统到系统某一个目录

准备设备并创建加密卷

插上硬盘后读取为 /dev/sda(电脑上硬盘是 NVMe 的),首先创建加密块设备:

# cryptsetup luksFormat /dev/sda
WARNING!
========
This will overwrite data on /dev/sda irrevocably.

Are you sure? (Type uppercase yes): YES
Enter passphrase for /dev/sda:
Verify passphrase:

验证设备情况:

# cryptsetup luksDump /dev/sda

LUKS header information for /dev/sda

Version:        1
Cipher name:    aes
Cipher mode:    xts-plain64
Hash spec:      sha256
Payload offset: 4096
MK bits:        256
MK digest:      76 e3 6a ec 43 87 27 77 25 dc 84 3c 06 7f 81 7e 29 a7 f0 85
MK salt:        92 e8 a4 1d aa ab 7b 85 21 bb 5f 55 0a 27 ed 03
                ec 7d 47 8f 78 67 7a c2 77 25 61 20 22 07 d5 36
MK iterations:  183317
UUID:           601a22a0-0888-4917-9047-4c8f15364f8b

Key Slot 0: ENABLED
        Iterations:             2876750
        Salt:                   d0 2a 56 0d 30 5d 24 d3 29 2a ec 19 fc 63 90 f8
                                dd c1 6e 02 38 c6 e1 85 5f 20 b6 b7 93 ab f1 08
        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

注意到底下有 Slot 的概念,对于加密卷的设备并不只有一种解密的方式,比如一个 Slot 可以留给 Yubikey 用,然后就有了 YubiKey Full Disk Encryption 的操作。

修改加密卷密码

LUKS 加密设备没法直接修改密码,而是先创建一个新的密码,然后再删除掉旧的密码,新建一个密码的方式如下:

# cryptsetup luksAddKey /dev/sda
Enter any existing passphrase:  # 此时输入任意一个密码
Enter new passphrase for key slot:
Verify passphrase:

再次执行 cryptsetup luksDump /dev/sda 可以看到:

Key Slot 0: ENABLED
        Iterations:             2876750
        Salt:                   d0 2a 56 0d 30 5d 24 d3 29 2a ec 19 fc 63 90 f8
                                dd c1 6e 02 38 c6 e1 85 5f 20 b6 b7 93 ab f1 08
        Key material offset:    8
        AF stripes:             4000
Key Slot 1: ENABLED
        Iterations:             2830164
        Salt:                   c2 ce e5 b0 cb 85 b4 dc c0 06 89 53 81 27 35 e5
                                ca 28 12 41 4b 16 93 57 ce 9c d3 5b 84 a0 69 4a
        Key material offset:    264
        AF stripes:             4000

这个时候两个密码都可以用来解开这个加密设备,此时我们删除掉第一次创建的密码,现在通过以上的 Key Slot 我们并不能判断出哪一个 Slot,所以我们可以先尝试用某一个密码解开一下,然后让 LUKS 告诉我们用的是哪一个 Slot,指令如下:

# cryptsetup -v open /dev/sda dot
Enter passphrase for /dev/sda:
Key slot 0 unlocked.
Command successful.

好的,我知道旧密码是 Slot 0,抹了它!

注意,如果手滑的话是可以直接把一個卷的所有 Slot 给抹完导致完全没有办法访问到那个设备的,所以,谨慎操作!

# cryptsetup luksRemoveKey /dev/sda
Enter passphrase to be deleted:

这里直接输入你需要抹除的 Slot 对应的密码,如果有两个 Slot 密码一样的话,会抹除第一个,如果需要抹除两个的话,执行这个指令两遍就好了。

初始化加密卷

此时我们解密这个块设备并且 map 到 /dev/mapper/dot 上,为后续创建文件系统和挂载做准备:

# cryptsetup open /dev/sda dot
Enter passphrase for /dev/sda:

这个时候,我们的加密设备已经解开并且 map 出来了,我们给 map 出来的块设备创建文件系统。

此时 fdisk -l 可以看到出现了两个设备,这个时候请自动忽略掉 /dev/sda,并且假设 /dev/mapper/dot 才是我们真正的设备(硬盘).

Disk /dev/sda: xxx GiB, xxx bytes, xxx sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes


Disk /dev/mapper/dot: xxx GiB, xxx bytes, xxx sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes

给块设备格式化为 ext4 文件系统:

# mkfs -t ext4 /dev/mapper/dot
mke2fs 1.44.2 (14-May-2018)
Creating filesystem with xxx 4k blocks and xxx inodes
Filesystem UUID: c4b26ca1-d017-4996-937b-9fa3c61d3050
...
Allocating group tables: done
Writing inode tables: done
Creating journal (xxx blocks): done
Writing superblocks and filesystem accounting information: done

挂载加密卷

挂载设备并检查挂载情况:

# mount /dev/mapper/dot /media/dot/
# df -h
Filesystem       Size  Used Avail Use% Mounted on
... 省略无关内容...
/dev/mapper/dot   xxxG   45M   xxxG   1% /media/dot

关闭加密卷

关闭整个设备分为以下两步:

  1. 解除挂载
  2. 关闭(锁上)加密卷设备

对于如上操作来说,解除挂载只需要如下指令:

# umount /media/dot

关闭(锁上)加密卷设备:

# cryptsetup close dot

一点题外话

如果你的设备和你在同一个区域 / 国家的话,加密你的设备只能防止因为设备失窃带来的信息泄漏或者让你知道你的设备正在被第三方尝试获取(比如在你睡着的时候偷走设备进行取证),真正隐私的信息还是尽量做到隐藏或者放在一个对你没有司法管理权的区域,毕竟再好的加密,也没法抵抗一根 5 美元不到的棍子,人的因素,永远是信息安全中最弱的一环。

此外,加密不等于备份,对于一个非备份用途的全盘加密磁盘来说,增量备份会变得更加困难,所以,建议此类使用场景的用户加入备份的元素,此外,给加密卷的 Header 和 Key-Slots 加密一下吧,方法见第二个参考链接。

References

  1. Disk encryption - ArchWiki

  2. Frequentlyaskedquestions · Wiki · cryptsetup / cryptsetup · GitLab

----------------------------------------------------------------------

cryptsetup/LUKS tutorial

This short tutorial will guide you in encrypting a drive with cryptsetup and LUKS scheme.

Before starting, if the device had previous data on it, it’s best to delete any filesystem signatures that may be on it. Assuming that the drive we operate is /dev/sda you can use the following command to remove the signatures:

$ sudo wipefs --all /dev/sda --no-act

Remove the --no-act flag to actually modify the disk.

The next step is to actually format the drive using LUKS. This is done using the cryptsetup utility.

$ sudo cryptsetup luksFormat --type=luks2 /dev/sda

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

Are you sure? (Type 'yes' in capital letters): YES
Enter passphrase for /dev/sda: 
Verify passphrase: 

The command will prompt you to enter a passphrase for the encryption and should take a few seconds to complete.

The next step is to add an appropriate entry to crypttab which will simplify starting the dm-crypt mapping later. Add the following line to /etc/crypttab:

archive_crypt UUID=114d42e5-6aeb-4af0-8758-b4cc79dd1ba0 none luks,discard,noauto

where the UUID is obtained through lsblk /dev/sda -o UUID or a similar command. The archive_crypt is the name for the mapped device. It will appear as /dev/mapper/archive_crypt when the device is mapped. The none parameter specifies that no keyfile is used and the system should prompt for an encryption passphrase instead. The noauto, means not to attempt to load the device automatically upon boot. discard should be used if the underlying device is an SSD.

You can test everything works so far by opening and loading the LUKS device:

$ sudo cryptdisks_start archive_crypt

While the device is now encrypted, there is a possible leakage of metadata such as used blocks as an attacker can discern used vs unused blocks by examining the physical drive. This and other side-channel leaks can be mitigated by simply wiping the contents of the encrypted device.

$ openssl rand -hex 32 | openssl enc -chacha20 -in /dev/zero -pass stdin -nosalt | sudo dd if=/dev/stdin of=/dev/mapper/sda_crypt bs=4096 status=progress

We could also have used /dev/urandom but the above technique is much faster.

Now we can create the actual filesystem.

$ sudo mkfs.btrfs --label archive /dev/mapper/archive_crypt

At this point we’re actually pretty much done. You can add and entry to /etc/fstab to easily mount the filesystem and you’re done.

/dev/mapper/archive_crypt /home/guyru/archive btrfs noauto,user 0 0

------------------------------------------------------------------

加密挂载硬盘


利用cryptsetup可以实现对硬盘的加密挂载,本文简单介绍如何使用

参考:https://blog.csdn.net/yifan850399167/article/details/80170215

加密初始化

# 加密某个硬盘的某个分区
cryptsetup luksFormat /dev/sdc1
# 要键入YES,并设置密码

# 解密这个分区,并进行硬着
cryptsetup open /dev/sdc1 fgn-disk-mapper
# 要输入密码
ll /dev/mapper/
lrwxrwxrwx. 1 root root       7 Nov 23 18:29 fgn-disk-mapper -> ../dm-2

# 格式化这个解密分区,然后挂载
mkfs.ext4 /dev/mapper/fgn-disk-mapper
mount /dev/mapper/fgn-disk-mapper /mnt/fgn-disk/

# 解除挂载并解除映射
umount /mnt/fgn-disk/
cryptsetup close fgn-disk-mapper

挂载

cryptsetup open /dev/sdc1 fgn-disk-mapper
# 要输入密码
mount /dev/mapper/fgn-disk-mapper /mnt/fgn-disk/

解挂

umount /mnt/fgn-disk/
cryptsetup close fgn-disk-mapper