Die Stärke der Sicherheit der drei besten Cipher/Verschlüsselungsarten ist wie folgt, der sicherste steht oben:
CryptSetup - ganzes Dateisystem verschlüsseln)GPG - einzelne Dateie verschlüsseln) → GPG-Verschlüsselung mit PasswortopenSSL - einzelne Dateie verschlüsseln) → OpenSSL-Verschlüsselung mit Passwort# cryptsetup --help | tail -n 8
Vorgabe für die Durchlaufzeit für PBKDF2 mit LUKS: 2000 Millisekunden
Vorgabe für PBKDF für LUKS2: argon2i
Iterationszeit: 2000, benötigter Speicher: 1048576 kB, parallele Threads: 4
Standard-Verschlüsselungsparameter:
Loop-AES: aes, Schlüssel 256 Bits
plain: aes-cbc-essiv:sha256, Schlüssel: 256 Bits, Passphrase-Hashen: ripemd160
LUKS1: aes-xts-plain64, Schlüssel: 256 Bits, LUKS-Header-Hashen: sha256, Zufallszahlengenerator: /dev/urandom
> cat /proc/crypto | grep -E '^name[ ]*: [a-z]' | cut -c 16- | grep -Ev '[(].*[)]' | sort | uniq aes cipher_null compress_null crc32 crc32c crct10dif deflate dh digest_null ghash jitterentropy_rng lzo lzo-rle md5 rsa serpent sha1 sha224 sha256 sha384 sha512 stdrng twofish zlib-deflate > cryptsetup benchmark --cipher serpent # Die Tests sind nur annähernd genau, da sie nicht auf den Datenträger zugreifen. # Algorithmus | Schlüssel | Verschlüsselung | Entschlüsselung serpent-cbc 256b 107,0 MiB/s 833,0 MiB/s
# cryptsetup benchmark
# Die Tests sind nur annähernd genau, da sie nicht auf den Datenträger zugreifen.
PBKDF2-sha1 1194277 iterations per second for 256-bit key
PBKDF2-sha256 1504413 iterations per second for 256-bit key
PBKDF2-sha512 996745 iterations per second for 256-bit key
PBKDF2-ripemd160 859488 iterations per second for 256-bit key
PBKDF2-whirlpool 583190 iterations per second for 256-bit key
argon2i 4 iterations, 1048576 memory, 4 parallel threads (CPUs) for 256-bit key (requested 2000 ms time)
argon2id 4 iterations, 1048576 memory, 4 parallel threads (CPUs) for 256-bit key (requested 2000 ms time)
# Algorithm | Key | Encryption | Decryption
aes-cbc 128b 635,0 MiB/s 2069,4 MiB/s
serpent-cbc 128b 79,4 MiB/s 312,0 MiB/s
twofish-cbc 128b 172,7 MiB/s 339,0 MiB/s
aes-cbc 256b 469,5 MiB/s 1606,0 MiB/s
serpent-cbc 256b 79,7 MiB/s 312,1 MiB/s
twofish-cbc 256b 173,5 MiB/s 339,3 MiB/s
aes-xts 256b 1379,1 MiB/s 1397,2 MiB/s
serpent-xts 256b 319,5 MiB/s 304,8 MiB/s
twofish-xts 256b 331,4 MiB/s 333,6 MiB/s
aes-xts 512b 1126,0 MiB/s 1163,6 MiB/s
serpent-xts 512b 320,7 MiB/s 305,0 MiB/s
twofish-xts 512b 332,6 MiB/s 333,3 MiB/s
Als erstes sollte man cryptsetup installieren. Bei Ubuntu geht das so:
> aptitude -y install cryptsetup
Mit CryptSetup kann man symetrisch verschlüsseln:
crypt.key)Image-Datei anlegen
### hier wird ein 700MB großes Image erstellt;
### mit diesem Aufruf wird eine 700 MB große Datei angelegt:
> dd if=/dev/zero of=daten.img bs=1M count=700
### mit diesem Aufruf (''dd'') wird eine 1 MB große Datei angelegt, die dynamisch bis 700MB groß werden kann:
> dd if=/dev/zero of=daten.img bs=1M count=1 seek=700
### mit diesem Aufruf (''shred'') wird eine 1 MB große Datei angelegt, die dynamisch bis 700MB groß werden kann:
> touch daten.img && shred -v -n1 -s700M daten.img
Image-Datei an eine LOOP-Gerätedatei binden
### nächstes freie LOOP-Gerät für die weiteren Schritte ermitteln (hier soll es das "/dev/loop0" sein) > /sbin/losetup -f /dev/loop0 ### Damit wir das gerade erstellte Image auch beschreiben können, muss dafür eine //Loop-Gerätedatei// angelegt werden. > /sbin/losetup -vf daten.img ### nachsehen, welche Gerätedatei für die Image-Datei verwendet wurde (hier ist es ''/dev/loop0'') > /sbin/losetup -l NAME SIZELIMIT OFFSET AUTOCLEAR RO BACK-FILE DIO LOG-SEC /dev/loop0 0 0 0 0 /.../daten.img 0 512 > /sbin/losetup -a /dev/loop0: [2050]:131046 (/.../daten.img)
Wichtig ist auch zu wissen, dass der Algorithmus nicht das alleinige Sicherheitsmerkmal hierbei ist! Die Verschlüsselungssoftware, die den Algorithmus verwendet, kann (bei einem schlechten Design) alles zu nichte machen. Solche Produkte gibt es auch unter Linux auch!
Dieser Forgang zerstört alle Daten auf der Image-Datei, die ggf. bereits drauf sind!
4096 Zufallswerte als Crypt-Schlüssel erzeugen und in der Schlüsseldatei speichern:
> touch crypt.key > chmod 0600 crypt.key > head -c 100000 /dev/urandom | tr -cd '[:alnum:]' | cut -b-4096 > crypt.key > wc crypt.key 1 1 4097 crypt.key
Diese Datei ist DER Schlüssel! Diese Datei muss auf jeden Fall sicher aufbewart werden und darf niemals in fremde Hände geraten! Sie muss genauso sicher aufbewart werden wie ein Passwort!
Verschlüsselungsalgorithmus auswählen ("Serpent" ist der sicherste; "Twofish" ist der 2.-sicherste; "AES" ist der US-Standard und nur 3% schneller als "Serpent") ⇒ /dev/loop0
2010
> /sbin/cryptsetup -q -c aes-xts-plain -s 512 -h sha512 luksFormat /dev/loop0 crypt.key > /sbin/cryptsetup -q -c twofish -s 256 -h sha512 luksFormat /dev/loop0 crypt.key > /sbin/cryptsetup -q -c serpent -s 256 -h sha512 luksFormat /dev/loop0 crypt.key
2020
> /sbin/cryptsetup -q -c aes-xts-plain -s 512 -h sha512 luksFormat /dev/loop0 crypt.key > /sbin/cryptsetup -q -c twofish-xts-plain -s 512 -h sha512 luksFormat /dev/loop0 crypt.key > /sbin/cryptsetup -q -c serpent-xts-plain -s 512 -h sha512 luksFormat /dev/loop0 crypt.key
### verschlüsselte Image-Datei auf die LUKS-Gerätedatei legen => /dev/mapper/cryptoluks > /sbin/cryptsetup luksOpen /dev/loop0 crypt.key cryptoluks cryptsetup status cryptoluks /dev/mapper/cryptoluks is active: cipher: serpent-cbc-plain keysize: 256 bits device: /dev/loop0 offset: 2056 sectors size: 1431544 sectors mode: read/write
Dieser Forgang zerstört alle Daten auf der Image-Datei, die ggf. bereits drauf sind!
### Verschlüsselungsalgorithmus auswählen ("Serpent" ist der sicherste; "Twofish" ist der 2.-sicherste; "AES" ist der US-Standard) => /dev/loop0
### 2010
> /sbin/cryptsetup -y -c aes-xts-plain -s 512 -h sha512 luksFormat /dev/loop0
> /sbin/cryptsetup -y -c twofish -s 256 -h sha512 luksFormat /dev/loop0
> /sbin/cryptsetup -y -c serpent -s 256 -h sha512 luksFormat /dev/loop0
### 2020
> /sbin/cryptsetup -y -c aes-xts-plain -s 512 -h sha512 luksFormat /dev/loop0
> /sbin/cryptsetup -y -c twofish-xts-plain -s 512 -h sha512 luksFormat /dev/loop0
> /sbin/cryptsetup -y -c serpent-xts-plain -s 512 -h sha512 luksFormat /dev/loop0
### verschlüsselte Image-Datei auf die LUKS-Gerätedatei legen => /dev/mapper/cryptoluks > /sbin/cryptsetup luksOpen /dev/loop0 cryptoluks > ls -lha /dev/mapper/ insgesamt 0 drwxr-xr-x 2 root root 80 Nov 21 11:14 . drwxr-xr-x 21 root root 4,8K Nov 21 11:14 .. crw------- 1 root root 10, 236 Nov 21 05:41 control lrwxrwxrwx 1 root root 7 Nov 21 11:14 cryptoluks -> ../dm-0 > cryptsetup status cryptoluks /dev/mapper/cryptoluks is active. type: LUKS2 cipher: serpent-xts-plain keysize: 512 bits key location: keyring device: /dev/loop0 loop: /dev/sda1 sector size: 512 offset: 32768 sectors size: 1953488896 sectors mode: read/write
Dieser Forgang zerstört alle Daten auf der Image-Datei, die ggf. bereits drauf sind!
Um auf das Image Daten rauf schreiben zu können, fehlt noch ein Dateisystem. Das werden wir im folgenden Schritt auf das verschlüsselte Image schreiben.
Welches Dateisystem ist jetzt das geeignetste? Nun folgende sind recht bekannt:
ext2 mit Journalext3 mit besserer Hardware-Fehlerkorrektur und sehr schnellem fsck, es macht sehr intensieven Gebrauch von Daten-Puffern
Als Dateisystem verwende ich meistens JFS oder ZFS, je nach Partitionsgröße und Verwendungszweck.
In diesem Fall ist JFS die bessere Wahl, weil es einfach übersichtlicher ist.
Ich verwende es unter Linux gerne, weil es dynamische Inodes hat (es können einem nie die Inodes aus gehen und ungenutzet Inodes belegen keinen Speicherplatz) und der fsck ist sehr schnell.
Dazu muss es natürlich erstmal installiert werden, auf Ubuntu-Linux geht das wie folgt:
> aptitude -y install jfsutils
JFS auf dem verschlüsselten Volumen anlegen:
> mkfs -t jfs /dev/mapper/cryptoluks
ggf. will man aber auch das aktuelle Linux-Standard-Dateisystem auf dem verschlüsselten Volumen anlegen, das geht dann so:
> mkfs -t ext4 -m 0 -L Sphinx /dev/mapper/cryptoluks
Man sollte sich angewöhnen, vor dem mount-Kommando immer das Dateisystem zu prüfen.
Denn man weiß ja nie, ob es beim "aushängen" Probleme gegeben hat.
Dateisystem prüfen und ggf. reparieren
> fsck -y /dev/mapper/cryptoluks
Dateisystem mounten:
> mount /dev/mapper/cryptoluks /mnt
> umount /mnt > /sbin/cryptsetup luksClose cryptoluks > /sbin/losetup -a /dev/loop0 ... > /sbin/losetup -d /dev/loop0
NUTZER="fritz" #CRYPTDATEI="/home/${NUTZER}/daten.img" CRYPTDATEI="/home/bin/daten.img" MDDEV="luks_crypt" MONTIEREN="/home/${MDDEV}" PATH="/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin" MOUNT="$(which mount)" UMOUNT="$(which umount)" PARAMETER="${1}"
#!/usr/bin/env bash #------------------------------------------------------------------------------# # # aptitude install cryptsetup # #------------------------------------------------------------------------------# ### erstellt im Jahre 2010; ### leider funktionieren diese CryptSetup-Einstellungen im Jahre 2020 ### nicht mehr so, wie sie stehen; man muss mit den Parametern "-s" und "-h" ### ein wenig rumspielen, bis es geht; VERSION="v2010093000" #------------------------------------------------------------------------------# if [ -r /home/etc/crypt.cfg ] ; then . /home/etc/crypt.cfg elif [ -r /home/bin/crypt.cfg ] ; then . /home/bin/crypt.cfg else echo "'/home/etc/crypt.cfg' und '/home/bin/crypt.cfg' sind nicht lesbar." exit 1 fi #------------------------------------------------------------------------------# if [ -z "${CRYPTDATEI}" ] ; then echo "$0 [cryptdatei.img]" else if [ -e "/dev/mapper/${MDDEV}" ] ; then if [ "${1}" != "start" ] ; then ### verschl. Datei ausklinken (umount) # # dieses Script muss unbedingt in # Gentoo: "/etc/conf.d/local.stop" # SUSE : "/etc/sysconfig/shutdown" # eingetragen werden! # ${UMOUNT} ${MONTIEREN} && rm -r ${MONTIEREN} #sync sleep 1 cryptsetup status ${MDDEV} | head -n1 cryptsetup luksClose ${MDDEV} cryptsetup status ${MDDEV} | head -n1 sleep 1 for LODEV in $(losetup -j ${CRYPTDATEI} | fgrep '/dev/loop' | awk -F':' '{print $1}') do losetup -d ${LODEV} done fi else if [ "${1}" != "stop" ] ; then ### verschl. Datei einklinken (mount) # # twofish (schnell+sicher) oder serpent (sehr sicher) #ALGORITHM="serpent" # 2010 ALGORITHM="serpent-xts-plain" # 2020 DATEISYST="jfs" # jfs (sicher) oder xfs (keine Fragmentierung) # #----------------------------------------------------------------------# ### nur zum initialisieren ### erstellen der Image-Datei # dd if=/dev/zero of=hdddatei.img bs=1024 count=107374182400 # dd if=/dev/zero of=${CRYPTDATEI} bs=1G count=100 # dd if=/dev/zero of=${CRYPTDATEI} bs=1G count=1 seek=100 # oder # touch ./hdddatei.img && shred -v -n1 -s700M ./hdddatei.img # touch ./hdddatei.img && shred -v -n1 -s30G ./hdddatei.img #----------------------------------------------------------------------# # LOAUSGABE="$(losetup -vf ${CRYPTDATEI} 2>&1)" LOOPDEV="$(echo "${LOAUSGABE}" | fgrep '/dev/loop' | awk '{print $NF}')" # losetup: could not find any free loop device # losetup: Konnte kein freies „loop“-Gerät finden if [ -z "${LOOPDEV}" ] ; then echo "'${LOAUSGABE}'" else echo "'${LOOPDEV}'" sleep 1 # #--------------------------------------------------------------# ### nur zum initialisieren # 2010: cryptsetup -y -c ${ALGORITHM} -h sha512 -s 256 luksFormat ${LOOPDEV} # 2020: cryptsetup -y -c ${ALGORITHM} -h sha512 -s 512 luksFormat ${LOOPDEV} #--------------------------------------------------------------# # cryptsetup status ${MDDEV} | head -n1 cryptsetup luksOpen ${LOOPDEV} ${MDDEV} # hier wird das Passwort abgefragt sleep 1 cryptsetup status ${MDDEV} # #--------------------------------------------------------------# ### nur zum initialisieren # mkfs -t ${DATEISYST} /dev/mapper/${MDDEV} #--------------------------------------------------------------# # mkdir -p ${MONTIEREN} fsck -y /dev/mapper/${MDDEV} && chown ${NUTZER} /dev/mapper/${MDDEV} # EINKLINKEN="${MOUNT} -t ${DATEISYST} /dev/mapper/${MDDEV} ${MONTIEREN}" echo "${EINKLINKEN}" ${EINKLINKEN} fi #echo "sleep 12" #sleep 12 fi fi fi if [ "${1}" == "stop" ] ; then for i in $(losetup -j ${CRYPTDATEI} | fgrep '/dev/loop' | awk -F':' '{print $1}') do losetup -d ${i} echo "${CRYPTDATEI} -> ${i} ist wieder frei" sleep 1 done fi
Aus Sicherheitsgründen sollte wir noch zwei Automatissmen einbauen, die unsere verschlüsselte Datei automatisch aushängen.
Dazu legen wir uns ein separates Stop-Script an. Würden wir dafür das "ein-Aus"-Script von oben verwenden, würde jedesmal, wenn der verschlüsselte Datenträger nicht eingehängt ist, ein Prozess gestartet werden, der nach der Passphrase fragt. Und das wäre sehr unschön.
Stop-Script:
# vi /home/bin/cryptodatei_aus_alle.sh
#!/bin/bash
#
# Dieses Script hängt alle eingehängten Crypto-Dateien aus.
#
for MDDEV in $(ls /dev/mapper/ | grep -v 'control')
do
MONTIEREN="/home/${MDDEV}"
LOOPDEV="$(cryptsetup status ${MDDEV} | grep '/dev/loop' | awk '{print $NF}')"
CRYPTODATEI="$(losetup ${LOOPDEV} | awk '{print $NF}' | awk -F'(' '{print $2}' | awk -F')' '{print $1}')"
umount ${MONTIEREN} && rm -fr ${MONTIEREN}
sleep 1
cryptsetup luksClose ${MDDEV}
sleep 1
losetup -a | fgrep ${CRYPTODATEI} | awk -F':' '{print $1}' | xargs losetup -d ${1}
echo "${CRYPTODATEI} ist wieder frei"
done
# chmod 0755 /home/bin/cryptodatei_aus_alle.sh
Damit das Script beim runter fahren des Systems ausgeführt wird, muss man den Aufruf in die entsprechende Datei eintragen.
Das wird bei jeder Distribution anders gemacht:
Bei Gentoo muss dieses Script erst noch aktiviert werden, wie es bei SUSE aussieht weiß ich nicht, und bei Ubuntu muss man sich dafür selber ein Stop-Script schreiben.
Das Stop-Script für Ubuntu könnte zum Beispiel so aussehen:
# vi /etc/init.d/stop-crypt
#! /bin/sh
### BEGIN INIT INFO
# Provides: stop-crypt
# Required-Start: $local_fs $all
# Required-Stop:
# Default-Start:
# Default-Stop: 0 6
# Short-Description: Stop Crypto-FS
# Description: entfernt das Crypto-Dateisystem
### END INIT INFO
NAME=stop-crypt
[ -x "$DAEMON" ] || exit 0
case "$1" in
stop)
/home/bin/cryptodatei_aus_alle.sh
;;
*)
echo "Usage: $NAME {stop}" >&2
exit 3
;;
esac
Jetzt am besten noch ausführbar machen:
# chmod 0755 /etc/init.d/stop-crypt
Dann muss das Script noch aktiviert werden:
# update-rc.d stop-crypt stop 20 0 6 .
Es ist auch Sinnvoll, im Sytem zu verankern, dass die verschlüsselte Datei automatisch um eine bestimmte Uhrzeit ausgehängt wird. Dann kann man es nicht vergessen (Sicherheit).
# vi /etc/crontab
00 20 * * * root /home/bin/cryptodatei_aus_alle.sh
als "root":
# /home/bin/cryptodatei_ein_aus.sh
als "user":
# su - -c /home/bin/cryptodatei_ein_aus.sh
oder bei Ubuntu
# sudo /home/bin/cryptodatei_ein_aus.sh
Diese Aufruffe kann man sich dann in seiner grafischen Arbeitsoberfläche als Schaltfläche oder "Knopf" hinterlegen.
Beim aushängen erscheint folgendes:
Passwort: /dev/mapper/cryptoluks is active: /dev/mapper/cryptoluks is inactive.
Beim Einhängen sieht das so aus:
Passwort: '/dev/loop0' /dev/mapper/cryptoluks is inactive. Enter passphrase for /dev/loop0: Key slot 0 unlocked. /dev/mapper/cryptoluks is active: cipher: serpent-cbc-plain keysize: 256 bits device: /dev/loop0 offset: 2056 sectors size: 1366008 sectors mode: read/write fsck from util-linux-ng 2.17.2 fsck.jfs version 1.1.12, 24-Aug-2007 processing started: 6/15/2010 17.27.34 Using default parameter: -p The current device is: /dev/mapper/cryptoluks Block size in bytes: 4096 Filesystem size in blocks: 170751 **Phase 0 - Replay Journal Log Filesystem is clean. /home/cryptoluks