Как-то раз на собеседовании меня усадили за компьютер, работающий на одном из дистрибутивов Linux, и предложили создать криптоконтейнер руками без спецсофта. Под "криптоконтейнером" интервьюер подразумевал архив с мощным шифрованием, хотя это технически неточное определение. Поэтому сразу оговорюсь, что криптоконтейнер подразумевает прозрачное шифрование, то есть возможность работать с файлами как с обычной ФС. Если понимать криптоконтейнер широко - как зашифрованный файл с данными, вариантов его создания может быть много. Если понимать криптоконтейнер строго - как прозрачное блочное устройство, то этому критерию отвечает только первый способ. Второй и третий способы - это не криптоконтейнеры, а скорее архивы с шифрованием, пусть и мощным. Интервьюер этот момент не уточнил. Ну что же, оставим это на его совести.
Уточнив условия, я озвучил и затем показал на практике три способа решения задачи.
Способ 1: cryptsetup + LUKS
Если на машине установлена cryptsetup.
Пару слов о том, что это вообще такое. Cryptsetup - это набор утилит для настройки шифрования дисковых разделов в Linux. Если на системе установлена cryptsetup, тогда все просто: мы создаем не архив с мощным шифрованием, а самый настоящий криптоконтейнер (LUKS/dm-crypt).
Делаем так:
Уточнив условия, я озвучил и затем показал на практике три способа решения задачи.
Способ 1: cryptsetup + LUKS
Если на машине установлена cryptsetup.
Пару слов о том, что это вообще такое. Cryptsetup - это набор утилит для настройки шифрования дисковых разделов в Linux. Если на системе установлена cryptsetup, тогда все просто: мы создаем не архив с мощным шифрованием, а самый настоящий криптоконтейнер (LUKS/dm-crypt).
Делаем так:
Bash:
# 1. создание файла-контейнера (100 МБ случайного мусора для маскировки), для больших контейнеров можно использовать fallocate, если предварительное заполнение случайными данными не требуется
dd if=/dev/urandom of=container.img bs=1M count=100
# 2. автоматический поиск свободного loop-устройства и привязка файла, сохраняем имя устройства в переменную, чтобы не ошибиться
LOOP_DEV=$(sudo losetup -f --show container.img)
# 3. форматирование под LUKS
sudo cryptsetup luksFormat $LOOP_DEV
# 4. открытие зашифрованного контейнера под именем mycontainer
sudo cryptsetup open $LOOP_DEV mycontainer
# 5. создание файловой системы ext4 внутри контейнера
sudo mkfs.ext4 /dev/mapper/mycontainer
# 6. создание точки монтирования и само монтирование
sudo mkdir -p /mnt/mycontainer
sudo mount /dev/mapper/mycontainer /mnt/mycontainer
# 7. передача прав текущему пользователю на запись
sudo chown -R $USER:$USER /mnt/mycontainer
Подчеркну, что пункт #7 - это пример настройки доступа, а не обязательная часть создания контейнера.
Способ 2: GPG с симметричным шифрованием
Допустим, что на системе не установлена cryptsetup, но зато установлена gpg. Если коротко, PGP/GPG - это инструмент для шифрования и цифровой подписи данных, который чаще всего используется для шифрования электронной почты на стороне клиента. Но PGP/GPG можно также использовать для симметричного шифрования файлов и архивов.
Для создания криптоконтейнера придется архивировать. Делаем так:
Способ 2: GPG с симметричным шифрованием
Допустим, что на системе не установлена cryptsetup, но зато установлена gpg. Если коротко, PGP/GPG - это инструмент для шифрования и цифровой подписи данных, который чаще всего используется для шифрования электронной почты на стороне клиента. Но PGP/GPG можно также использовать для симметричного шифрования файлов и архивов.
Для создания криптоконтейнера придется архивировать. Делаем так:
Bash:
tar czf - files/ | gpg --symmetric --cipher-algo AES256 -o archive.tar.gz.gpg
# здесь - (минус) указывает, чтобы tar писал в stdout, а не на диск - архив шифруется на лету
# без явного указания --cipher-algo GPG подставит алгоритм по умолчанию
# можно добавить ключик --armor, если нужен ASCII-формат
В данном случае я использовал симметричное шифрование. Безусловно, метаданные (что это не случайные байты, а PGP/GPG-формат) остаются и тривиально детектируются file/binwalk). Хочу подчеркнуть, что это лишь позволяет определить формат файла, но никак не влияет на стойкость шифрования. Скрытие формата контейнера само по себе не является существенным элементом защиты, и все-таки оставлять узнаваемые сигнатуры файлов - это нехорошо. Но это уже вопрос не криптографии, а OpSec. Так или иначе, интервьюер не обозначил этот момент как условие - задача скрыть содержимое архива была решена.
Способ 3: OpenSSL
Допустим, что на системе не установлена ни cryptsetup, ни gpg. Остается самый минималистичный вариант: openssl.
Для создания криптоконтейнера также придется архивировать. Делаем так:
Допустим, что на системе не установлена ни cryptsetup, ни gpg. Остается самый минималистичный вариант: openssl.
Для создания криптоконтейнера также придется архивировать. Делаем так:
Bash:
tar czf | openssl enc
Хочется добавить, что для хранения данных этот способ морально устарел. Исторически openssl enc плохо подходит для долговременного хранения данных: он не предоставляет современную схему аутентифицированного шифрования "из коробки", кроме того, magic bytes Salted__ в начале файла тоже детектируется. Поэтому сегодня подобный вариант скорее следует рассматривать как решение на крайний случай.
Напоследок: когда и какой способ использовать
Вариант 1 - для серьезной защиты. Вариант 2 - если нужно быстрое решение. Вариант 3 (наименее предпочтительный) стоит считать минимально достаточным при отсутствии других инструментов.
P.S. Да, существует VeraCrypt. Короткий ответ для тех, кто будет интересоваться, использую ли этот инструмент я: не использую. VeraCrypt имеет смысл там, где нужна кроссплатформенность (Windows/macOS/Linux) или совместимость с существующими контейнерами. Во всех остальных случаях LUKS, безусловно, предпочтительнее для пользователя Linux.
Напоследок: когда и какой способ использовать
Вариант 1 - для серьезной защиты. Вариант 2 - если нужно быстрое решение. Вариант 3 (наименее предпочтительный) стоит считать минимально достаточным при отсутствии других инструментов.
P.S. Да, существует VeraCrypt. Короткий ответ для тех, кто будет интересоваться, использую ли этот инструмент я: не использую. VeraCrypt имеет смысл там, где нужна кроссплатформенность (Windows/macOS/Linux) или совместимость с существующими контейнерами. Во всех остальных случаях LUKS, безусловно, предпочтительнее для пользователя Linux.