Is it possible to encrypt a hard disk with a key file instead of a password

disk-encryptionencryptionluks

Looking into hard disk encryption. the go to solution seems to be dm-crypt with LUKS using a password. I work with multiple independent hard disks mounted into a disk pool for reading. In this case, I have to type a password multiple times.

Is there a way for me to encrypt the hard disks with a key file, maybe put it on a USB drive and just plug it in when necessary??

Best Answer

One of the best ways to do this is to use a smart card with a crypto key on it to unlock the keys for your encrypted block devices. You will only need to enter the passphrase (called "PIN" by the tools but it's really a passphrase) once, after which it will be cached. This has the added advantage of protecting the encrypted data with something-you-have (the smart card itself, out of which the private key cannot be extracted) and something-you-know (the passphrase).

Format your /etc/crypttab like this:

mapper-name /dev/disk/raw-device /var/lib/filename-containing-encrypted-key \
    luks,keyscript=/lib/cryptsetup/scripts/decrypt_opensc

In Debian and derivatives, the initramfs-tools will notice the keyscript and copy all of the necessary tools and daemons for accessing the smart card to the initramfs automatically.

Information on setting up the smart card and creating (and encrypting) the keys is found in /usr/share/doc/cryptsetup/README.opensc.gz.

You can use a Yubikey 4 or Yubikey NEO among others for this purpose.

Implementation notes: This feature has rough edges and apparently doesn't work out of the box so YMMV. The last time I successfully achieved it, I had to add the following hacks:

  • Disable systemd because it disastrously tries to take over the whole process of setting up encrypted devices from /etc/crypttab but it knows nothing about keyscript which leads to a big FAIL. Luckily, in Debian, you can still opt out of systemd.
  • Install this fixer-upper script as /etc/initramfs-tools/hooks/yubipin because the built-in feature didn't install quite enough support to get the Yubikey to be usable from the initramfs. You may need to adjust this.

    #!/bin/sh
    
    PREREQ=cryptroot
    
    prereqs()
    {
        echo "$PREREQ"
    }
    
    case $1 in
    prereqs)
        prereqs
        exit 0
        ;;
    esac
    
    # /scripts/local-top/cryptopensc calls pcscd with the wrong path
    ln -s ../usr/sbin/pcscd ${DESTDIR}/sbin/pcscd
    mkdir -p "${DESTDIR}/usr/lib/x86_64-linux-gnu"
    # opensc-tool wants this dynamically, copy_exec doesn't know that
    cp -pL /usr/lib/x86_64-linux-gnu/libpcsclite.so.1 "${DESTDIR}/usr/lib/x86_64-linux-gnu/libpcsclite.so.1"
    mkdir -p "${DESTDIR}/lib/x86_64-linux-gnu"
    # without this, pcscd aborts with a pthread_cancel error
    cp -pL /lib/x86_64-linux-gnu/libgcc_s.so.1 "${DESTDIR}/lib/x86_64-linux-gnu/libgcc_s.so.1"
    # this gets copied as a dangling symlink, fix it
    rm "${DESTDIR}/usr/lib/pcsc/drivers/ifd-ccid.bundle/Contents/Info.plist"
    cp -pL /usr/lib/pcsc/drivers/ifd-ccid.bundle/Contents/Info.plist "${DESTDIR}/usr/lib/pcsc/drivers/ifd-ccid.bundle/Contents/Info.plist"
    # pcscd needs this to open the reader once it has found it
    cp -pL /lib/x86_64-linux-gnu/libusb-1.0.so.0 "${DESTDIR}/lib/x86_64-linux-gnu/libusb-1.0.so.0"
    
  • Install another script as /etc/initramfs-tools/scripts/local-bottom/killpcscd to clean up:

    #!/bin/sh
    
    set -e
    
    PREREQ=cryptopensc
    
    prereqs()
    {
        echo "$PREREQ"
    }
    
    case $1 in
        prereqs)
            prereqs
            exit 0
            ;;
    esac
    
    # because cryptopensc does not do it properly
    killall pcscd
    
Related Question