How to securely encrypt files on Linux with Dm-crypt? Linux bootloaders supporting full disk encryption? Debian disk encryption.

In this article, I will tell you how to create a hidden crypto container. standard means Linux OS (LUKS and cryptsetup). Built-in features of LUKS (such as using external headers and placing real data at a given offset) allow the user to access data hidden inside an existing container, as well as deny the existence of such data.

UPD: Since this post was ready a month ago, then I could not even imagine such a strange and unexpected death of the project. Well, yes, it may not have completely died yet, let's see ... Nevertheless, in this text, I decided to leave all references to TrueCrypt as it is.

What is "plausible deniability"?

You can find a very long and detailed description of this concept on Wikipedia: http://en.wikipedia.org/wiki/Plausible_deniability . In short, this means that you can have something (or could have done something), the presence of which cannot be suspected or proven by anyone (unless you admit it yourself, of course). And afterwards you can deny the existence (or the fact of doing) this something, if someone wants to accuse you, since (I repeat) this fact is unprovable. Well, for example, if a child kicked his little brother in the ass, and the brother went to seek justice from his parents, what would happen in this case?

Well... As if nothing happens. Because this dude will refuse, and the parents, formally speaking, will not be able to catch him by the hand (because, firstly, there are stupidly no witnesses, and secondly, the younger brother can play his dirty game). Thus, no one will be punished. Well, or they will punish both for every fireman. This was just an example of the use of the possibility of plausible deniability by a child prone to aggression. But you and I, of course, are white and fluffy, and we will use hidden containers solely to protect our personal data from bad guys. So right? Of course, “what is “good” and what is “bad”” is a separate issue ... However, more to the point.

General idea of ​​implementation

Suppose we want to store some important data inside an encrypted file. In general, we will use some kind of crypto-protection program that will do all the dirty work for us. We may want to treat the encrypted file as if it were a virtual disk, and this narrows down the number of potential candidates considerably. However, there is one "but". Almost all such programs work with a file as with one piece of encrypted data. Let me explain: the user usually has one password (and maybe a few "spare") for all data inside the container. This means there is at least one weak link: the container password. I don't want to mention that the password must be cryptographically strong, because that's a common truth. What I mean is that if the user gives up that password for some reason (e.g. under duress), all data will be read. And this fact seems sad and completely wrong to me ...

However, there is generally hope. :) For example, there is a program like , which is quite smart. The user can create two containers in one file: one is a “dummy” one with a certain number of “forbidden”, but relatively safe files, and the other is a real one, with data that should not be exposed under any circumstances. Thus, TrueCrypt asks for two different passwords when a user wants to create such a "double" container. During operation, the user enters only one password for the "real" part and works with it. In the event that, under pressure from external circumstances, the user is forced to disclose the contents of the container to third parties, he simply enters a different password, and TrueCrypt opens the "fake". I emphasize (and this is really important) that there is no way to prove the presence of the hidden part if the researcher does not know the corresponding password.

And now let's quickly figure out how this junk works ... In fact, everything is very simple. The software divides the container file into two (generally speaking, unequal) parts. The first part, which may be relatively small, contains specially prepared data; the second one is real. Accordingly, the program must be able to work with two different headers (configurations) for two different parts, and also be able to choose which part to decrypt depending on the password entered by the user. And this, I must say, is not the most trivial part of the work. Well, simply because "officially" only one "fake" configuration should be visible: if the container has a standard header, it should only be a "fake" header; if the container parameters are stored in a separate config, this config should allow decrypting only the "fake" part. And after deciphering the "fake" part, there should not be a single hint of the presence of the real one. They must be absolutely independent. Moreover, when the “fake” part is opened, the software should show the full capacity of the crypto container, even if the volume of this part is much smaller.

So what about LUKS?

Well, here we have good news and… erm… even more good news.

The good news is that cryptsetup can decrypt and mount volumes created by TrueCrypt ". Read only, however, but this is nonsense. Since there is better news. Namely, we can create "hidden" containers exclusively using . Moreover, this utility allows you to create any number of "hidden" parts. Naturally, within reasonable limits. And here is how it can be done.

But before continuing,

HUGE FAT SCARY WARNING!!!

  • Anything described below can cause irreversible data loss.
  • In your country, the use of strong cryptography may be prohibited, so you may be imprisoned not for real information, but simply for having a crypto container that will be found on your screw.
  • Cryptography can protect your data, but it won't protect you from torture. A hidden container can help keep valuable information, but you can't deny its presence in case of betrayal or denunciation.
  • The guys who are interested in your encrypted data may not be as dumb as you expected. Even if they cannot prove the presence of a hidden part of the container, they may well lock you in the same cell with seasoned criminals, and in a couple of days you will remember all the passwords for all the hidden data.
  • If you have close people (girlfriend / boyfriend, relatives, friends), they can just as well become a target for hard pressure. And this will certainly help you remember everything in general much faster, including what you didn’t even know.

So it's better to think twice about how much information is more valuable than your life and the lives of your loved ones. And make a backup. Just in case.

Well, man cryptsetup can tell us a lot interesting details about the command line options of this utility. Well, for example, let's look at the --header option:

Well, okay. This means that we can now have a data volume filled with random junk, with absolutely no meaningful signatures. The description of this option contains a little more information, cautions and warnings, but in the bottom line, this is all that is required. However, I highly recommend reading this excellent guide.

Another very useful option is --align-payload , which allows you to position the real data at a certain offset relative to the beginning of the volume:

And this is also cool, because now we can freely shift our data to any part of the volume. You get the idea, right?

  1. We initialize the volume for encryption: we completely overwrite it with random data.
  2. We make an “official” encrypted volume and drop a little infected varese, coiled muzla, pron useful free software, recordings from your amateur rock band, love movies, etc., in general, for which you will be given no more than two years of probation.
  3. Using the above esoteric cryptsetup options, we create a hidden volume (inside the “official”) and transfer its title to external media. Here you can store really dangerous information (such as your kindergarten photos or plans to conquer the world).

Actually, folks, that's all. No magic. Naturally, you can't stuff the "official" encrypted disk to capacity for the simple reason that part of its space is given over to a hidden container. And, as I said at the beginning, you can, if you like, create multiple hidden drives following the same logic.

Here ... And if you still need details, then especially for you -

Walkthrough

Attention!

The following commands will destroy your data if executed without turning on the brains. Lost information cannot be recovered because utilities like dd operate at a low level (that is, below the filesystem level). Therefore, it will not be possible to roll back changes or undo their effect, even if you abort immediately after launch.

In short, don't do this unless you can think of a meaningful explanation for how each step relates to your goals. And make a backup. Right now.

So let's say we have a device with multiple partitions. Let it be, for example, /dev/sdb. And let /dev/sdb1 be a relatively small (8GB) partition dedicated to encryption. We will split it 5 to 3, where the 5 GB part will be "official" and the 3 GB part will be hidden. Let's also assume that we will keep the key for the encrypted disk in /etc/keys, and the header of the hidden container, respectively, on an external USB drive, which we will mount in /media/user/ExtUSBStick. I assume you already know what permissions you need to set on the keystore, how to configure encfs / ecryptfs to securely store confidential data on insecure devices, and also that it makes sense to copy real secret keys and store them in several geographically separated safes.

Well, okay, I’m tying grumbling and moving on to the essence of the issue.

    Device initialization /dev/sdb1:

    Dd if=/dev/urandom of=/dev/sdb1 bs=16M

    We make a key for an encrypted volume. 512 bits (64 bytes) for our purposes through the roof:

    Dd if=/dev/urandom bs=64 count=1 >/etc/keys/secret.key 2>/dev/null

    Encrypt the volume using the newly created key:

    Cryptsetup luksFormat /dev/sdb1 /etc/keys/secret.key

    Open the encrypted device and configure the mapping in secretdata:

    Cryptsetup luksOpen --key-file /etc/keys/secret.key \ /dev/sdb1 secretdata

    Create on an encrypted volume file system(e.g. btrfs):

    Mkfs.btrfs -L SecretData /dev/mapper/secretdata

    ... and mount it:

    Mount /dev/mapper/secretdata /var/secretdata/

    Keeping in mind the 5 gig limit, set the subvolume quota:

    Btrfs quota enable /var/secretdata/

    Since btrfs quotas only apply to subvolumes, let's create one such thing:

    brfs subvolume create /var/secretdata/workingvolume

    ... and apply the specified quota to it (note that btrfs subvolumes can be mounted as regular filesystems, so you may find it more convenient to mount this particular subvolume instead of the entire fs later):

    btrfs qgroup limit 5G /var/secretdata/workingvolume

    We fill it with some data:

    debootstrap --variant=buildd testing /var/secretdata/workingvolume

    That's all, now you can forget about this part:

    Umount /var/secretdata cryptsetup luksClose secretdata

    Now let's create a "fish" for the header and stuff random garbage into it:

    Dd if=/dev/urandom of=/media/user/ExtUSBStick/hidden.head bs=4M count=1

    And now comes the very moment when the real magic begins. (What? Did I say there was no magic? So I lied.) We use the same secret key, however, not in its entirety, but only half (from an offset of 32 bytes). However, the remaining 256 random bits are quite capable of making a good key. Then we will separate the header and put it on the flash drive. Finally, we tell cryptsetup "y" that we want to offset our hidden container by 5GB (i.e. 10485760 512-byte blocks) from the beginning of the volume:

    Cryptsetup --keyfile-offset 32 ​​--header /media/user/ExtUSBStick/hidden.head \ --align-payload 10485760 luksFormat /dev/sdb1 /etc/keys/secret.key

    Yes, it's that simple. Now let's open a new encrypted device:

    Cryptsetup luksOpen --key-file /etc/keys/secret.key --keyfile-offset 32 ​​\ --header /media/user/ExtUSBStick/hidden.head /dev/sdb1 realsecretdata

    Let's roll any fs we want:

    Mkfs.btrfs /dev/mapper/realsecretdata

useful links

For those who want to know a little more, here are some additional sources of information:

  • disk encryption, general information on disk encryption: https://wiki.archlinux.org/index.php/Disk_encryption
  • Denied Encryption, the concept is somewhat narrower than "plausible deniability", referring only to the field of cryptography: https://en.wikipedia.org/wiki/Deniable_encryption
  • TrueCrypt

Disk (a la TrueCrypt). I know there has been work to add encryption support to GRUB2, but it's not ready yet. Any other options?

(Note that I really mean full disk encryption here, including /boot)

Most of the answers describe a setup where /boot is not encrypted, and some of them try to explain why an unencrypted /boot should be fine.

Without getting into a discussion of why I really need /boot to be encrypted, here is an article that describes exactly what I need, based on a modified version of GRUB2:

  • http://xercestech.com/full-system-encryption-for-linux.geek

The problem is that these modifications don't seem to be supported in the current GRUB2 codebase (or maybe I'm missing something).

8 Solutions collect form web for “Linux bootloaders supporting full disk encryption?”

I think that Current version GRUB2 does not support loading and decrypting LUKS partitions by itself (it contains some ciphers, but I think they are only used to support passwords). I can't check out the experimental development branch, but there are some hints on the GRUB page that some work is planned to be implemented that you want to do.

Update (2015) : latest version GRUB2 (2.00) already contains the code to access LUKS and GELI encrypted partitions. (The xercestch.com link that the OP provided mentions the first fixes for this, but they are now included in the latest version).

However, if you are trying to encrypt the entire drive for security reasons, please note that an unencrypted bootloader (such as TrueCrypt, BitLocker, or modified GRUB) does not provide more protection than an unencrypted /boot partition (as noted by SP in the comment above). Anyone with physical access to the computer can just as easily replace it with a custom version. It's even mentioned in the xercestech.com article you linked:

To be clear, this in no way makes your system less vulnerable to an offline attack if an attacker were to replace your bootloader with their own or redirect the boot process to boot their own. own code, your system may still be compromised.

Note that all full disk encryption software products have this weakness, whether they use an unencrypted bootloader or an unencrypted boot/preboot partition. Even products that support TPM (Trusted Platform Module) chips, such as BitLocker, can be deployed without changing hardware.

The best approach would be:

  1. decrypt at the BIOS level (in motherboard or drive adapter or external hardware [smart card], with or without a TPM chip), or
  2. carry the PBA (preboot authorization) authorization code (the /boot partition in this case) on a removable device (for example, a smart card or USB drive).

To do it the second way, you can check the Linux Full project Disk Encryption(LFDE) at: http://lfde.org/ which provides a post-installation script to move the /boot partition to external USB drive by encrypting the key with GPG and storing it on USB too. This way, the weak part of the boot path (the unencrypted /boot partition) is always with you (you will be the only one with physical access to the decryption of the code and the key). ( Note: this site has been lost and the author's blog has disappeared as well, however you can find the old files at https://github.com/mv-code/lfde just noting that the last development was done 6 years ago). As an easier alternative, you can mount an unencrypted boot partition on a USB drive when you install the OS.

Sincerely, M.V.

Make your first RAMdisk and /boot folder unencrypted.

This will invoke a "minimal" kernel with drivers and support to switch to a "real" root filesystem that is encrypted.

Before you state "it's a hack", remember - most (if not all) Linux distributions are booted by default today. This explicitly allows your system to load and load the root FS using modules that need to be loaded from the file system. (Kind of a chicken and egg problem). For example, if your root file system was on a hardware RAID volume and you needed to load its driver before you could mount the root FS.

I looked at the link you posted - though boot partition no, the hard drive still has an unencrypted bootloader that can be accessed and compromised by a malicious attack. I've been looking for a similar setup that doesn't have any unencrypted data on the hard drive, but so far I've only come up with running the bootloader from a removable drive.

I believe that most of what you need is an instruction on how to install an OS with an encrypted HD in the first place.

Ubuntu has a nice page with instructions on how to create encrypted partitions, LMVP, folders, etc, just your version of your distro...

No, I don't think so.

Do you really need to encrypt/upload? I suspect not. The rest of the file system can be encrypted with normal software Linux which resides in the initramfs in /boot and prompts the user accordingly.

You seem to be asking for something that can't be done and comparing it to Windows solution, which hides the implementation from you, but actually does the same thing that Linux does.

The closest solution I can think of is to use HDD, which implements password security and encryption. Some Thinkpad laptops use these hardware solutions.

The answer is in the article. "This is now possible with extensions to the next generation GRUB2 bootloader that has been patched to support more than just" and "we want to install a new luks grub2-enabled image later", and "Now we will compile the GRUB2 source with LUKS support. There seems to be a fix or extension that you need to get and enable with GRUB2 or the GRUB2 forked source.

Grub2 version 2.02~beta3 can do a lot that Grub2 version 2.02~beta2 can't do, verified by me:

  1. Booting using a Super Grub 2 disk
  2. Type "c" to go to the command line
  3. Enter the commands to mount the encrypted partition I want
    • insmod lux
    • cryptomount (hd0, #) // where # represents the encrypted partition
  4. Enter key phrase and enter some commands
    • multiboot (crypto0) /grub/i386-pc/core.img
    • shoe

This will boot another Grub2 which is inside the encrypted partition, no evil crazy attack here... I boot from a CD (read-only) and then mount the encrypted partition (not a passphrase, anything!), then booting from inside an encrypted partition and booting Grub2 with its own menu, etc.

Warning: Grub2 version 2.02~beta2 can't do the same as it has some bugs (which appear to be fixed in Grub2 version 2.02~beta3) related to the cryptomount command...

beta2 bugs I'm talking about are:

  1. It doesn't actually mount the encrypted partition, so it doesn't let you access (crypto0)/*
  2. If there is more than one encrypted partition, using cryptomount -a requires only one passphrase
  3. After starting cryptomount once, it starts up again, does nothing

on beta 3:

  1. It actually mounts the encrypted partition and allows you to access files via (crypto0)/* or (crypto1)/* etc if more than one mounted at the same time
  2. It asks for each passphrase (one per encrypted section)
  3. This allows you to run it as many times as you like, you can install one, then another, etc.

Side note: I haven't figured out how to unmount them other than rebooting or loading another or one boot loader grub2/other etc.

I hope this helps clear things up, and I hope the 2.02~beta3 version of Grub2 gets integrated into the LiveCD so we can install it without having to compile it ourselves.

PD: With a Super Grub 2 drive, I don't see a way to install Grub2 version 2.02~beta3 on an MBR/boot partition, etc.

In this article, I will try to compare the performance of various encryption systems under linux. In theory, of course, it is known which system is more productive, and attempts to calculate the performance different systems were (). Truecrypt even contains a built-in benchmark (which shows, however, the performance on RAM, it can only be used to evaluate the speed of different encryption algorithms). I will do something different - I will measure the speed of a file system encrypted by various means as a percentage compared to a conventional unencrypted file system.


We will encrypt a separate partition on a separate HDD that does not contain a root file system with the algorithm used by default in each specific case. As an ordinary user, I don't understand the nuances of encryption standards (for example, how RIPEMD-160 hashing differs from Whirpool, which of these modes is faster, which one contributes to higher security), so we just rely on the fact that the manufacturers of each software product chose sufficiently crypto-resistant default parameters. Maybe this is not entirely correct, because the performance of various encryption algorithms is not the same. If desired, of course, you can change the type of encryption, but I'm not sure that in all tested products there is an absolutely identical set of algorithms. We will test:

3) eCryptfs is the default system offered to Ubuntu users for encrypting home directories, which is why it is included in this test. Works on top of an existing file system. Encrypts each file separately, so everyone can see the rights, dates of modification, the number of encrypted files; by default, filenames are also visible, although there is an option to encrypt them. The least functional tool ever.

4) EncFS - an approximate analogue of eCryptfs, but uses FUSE.

So, for the tests, a separate machine of a rather advanced age was allocated in the following configuration: CPU - Intel Celeron 2000Mhz, RAM - 512 Mb DDR PC2700, system HDD- WD Caviar SE 5400 RPM 80Gb, test HDD - WD Caviar SE 7200 RPM 80Gb.
OS - Ubuntu 12.04 LTS, versions of all software are relevant for the repositories of this OS at the time of this writing (Truecrypt 7.1a-linux-x86 is not from the repositories).

We will test the default ext4 file system for most distributions. For performance testing, we will use the iozone3 utility and a shell script written “on the knee” to measure the percentage difference in the tests.

Counting script. No special attention was paid to the cleanliness of the code, the only criterion for writing was the presence of the correct result.

#!/bin/sh gendifffile () ( #the procedure generates a file that is convenient for parsing. First, lines that cannot be parsed are truncated; secondly, the first two numbers in each line are truncated, indicating #file size and record size, respectively ; thirdly, the entire file is output line by line - #one test result per line cat $1 | while read LINE ; do echo $LINE| grep "^[[:space:]]*[[:digit:]]" | awk "(for (i=3;i<=NF;i++) {print $i}}" done > > $2 ) getline () ( #procedure outputs line number $2 of file $1 head -n $2 "$1" | tail -n 1 ) compare () ( #procedure compares file $1 and $2 line by line, calculating the percentage difference of each pair of tests #then calculates arithmetic mean, by what percentage is faster or slower #file containing the first group of tests, the file containing the second group P=0 MAX=0 L1=`cat "$1" | wc -l` #number of tests in the file L2=`cat "$2" | wc -l` if [ $L1 -ne $L2 ]; then #if the files contain a different number of tests, then we will not compare them echo error return fi STEP=$(($L1*5/100)) J=0 for I in `seq 1 $L1`; do J=$(($J+1)) if [ $J -eq $STEP ]; then J=0 echo "$((100*$I/$ L1))% completed ($I of $L1)" fi A=`getline "$1" $I` B=`getline "$2" $I` if [ `echo $A \> $B|bc -l` - eq 1 ]; then D=`echo "100-($B*100/$A)"|bc -l` if [ `echo $D \> $MAX| bc -l` -eq "1" ]; then MAX=$D sleep 5 fi else D=`echo "100-($A*100/$B)"|bc -l` if [ `echo $D \> $MAX| bc -l` -eq "1" ]; the n MAX=$D sleep 5 fi D="-$D" #if the value has a "-" sign, this test was faster # in the second file than in the first one fi P=`echo "$P+$D "| bc -l`done P=`echo $P/$L1| bc -l` #calculate the arithmetic mean echo PERCENT=$P MAX_PERCENT=$MAX ) genaverage () ( #the procedure for generating a file prepared for analysis, each line of which is the #arithmetic mean of the corresponding lines of all report files located in the analyzed directory AVG=` mktemp` F=`ls "$1"|wc -l` #number of files with reports in the specified directory #provided that only such files are stored there and nothing else #we will not check the correctness of this assumption if [ ! -d " $1" -o $F -lt 2 ]; then echo error >/dev/stderr #in this procedure, we will output all messages to stderr, since #stdout is substituted into another procedure rm -f $AVG exit fi TMP=` mktemp` find "$1" -type f| while read FILE; do #for each iozone report file in the given directory I=`mktemp` #gendifffile "$FILE" "$I" #names write all such files to "TMP" line by line echo "$I">>$TMP done L=`cat \`getline "$TMP" 1\`|w c -l` cat "$TMP"| while read LINE; do #a little checking is good L1=`cat "$LINE"| wc -l` #do all files contain the same number of tests if [ $L -ne $L1 ]; then echo error >/dev/stderr exit fi done STEP=$(($L*5/100)) J=0 for I in `seq 1 $L`; do J=$(($J+1)) if [ $J -eq $STEP ]; then J=0 echo "$((100*$I/$L))% done ($I of $L)" >/dev/stderr fi SUMFILE=`mktemp` #this way I get the value of the SUM variable from the nested loop SUM=0 cat "$TMP"| while read LINE; do SUM=$((`getline "$LINE" $I`+$SUM)) echo $SUM > "$SUMFILE" done echo `tail -n 1 "$SUMFILE"`/$F|bc -l >> $ AVG #get the arithmetic mean #and write it to the appropriate location #of the AVG file rm -f "$SUMFILE" done cat "$TMP"| while read LINE; do #delete temporary files rm -f "$LINE" done rm -f "$TMP" echo $AVG ) printf %b "\\033)