Шифрование файлов в Linux с помощью OpenSSL

Я продолжаю долгую, но интересную сагу, на тему шифрования информации в Linux с помощью самых разных, как простых так и сложных, методов. Если вам интересна эта тема, то возможно вы захотите прочитать одну из предыдущих статей о шифровании, как: Шифрование в Linux c использованием программы TrueCrypt, или Шифрование в Linux с использованием GnuPG. Тема сегодняшеней статьи, это шифрование с файлов с помощью ещё одного открытого инструмента – OpenSSL. Стоит отметить, что openssl прост в использовании и многофункционален, думаю все вы слышали, что некоторые соединения в интернете защищены с помощью ssl-шифрования, так вот с помощью SSL-шифрования можно шифровать и транспорт и локальные файлы. Читаем под катом, как это делается.

Немного об OpenSSL

Последнее время я активно интересуюсь темой шифрования файлов и криптологией в целом, тема интересная, захватывающая, но от части сложная, так как сопряжена с математикой и программированием. Так что такое OpenSSL? OpenSSL — это криптографический пакет с открытым исходным кодом для работы с SSL/TLS. Позволяет создавать ключи RSA, DH, DSA и сертификаты X.509, подписывать их, формировать CSR и CRT. Также имеется возможность шифрования данных и тестирования SSL/TLS соединений. (по версии Wikipedia).

Давайте сразу проясним для себя некоторые части этого определения. TLS – это так называемый “транспорт” или от английского — Transport Layer Security — криптографический протокол, обеспечивающий защищённую передачу данных между узлами в сети Интернет. SSL от английского Secure Sockets Layer — уровень защищённых сокетов — криптографический протокол, который обеспечивает установление безопасного соединения между клиентом и сервером, именно так нам объясняет Wikipedia понятия TLS & SSL и это верно.

Алгоритмы шифрования поддерживаемые пакетом OpenSSL:
Blowfish, Camellia ,DES, RC2, RC4, RC5, IDEA, AES, ГОСТ 28147-89, RSA, DSA, Diffie-Hellman key exchange, ГОСТ Р 34.10-2001, к слову я их тут в кучу налепил, а вообще они делятся на симметричные и асимметричные, если вы хотите узнать об этом больше, то читайте Wikipedia и по возрастающей.

Применение OpenSSL:

  • Создание RSA, DH и DSA ключей
  • Создание сертификатов X.509, CSR и CRL
  • Шифрование и дешифрование с помощью алгоритмов
  • SSL/TLS клиент и сервер тесты
  • Обработка, дешифровка и шифровка электронной почты

Практика

Нас будет интересовать пункт, шифрование и дешифрование файлов с помощью различных алгоритмов. Предположим у вас есть файл с именем file который требуется зашифровать.

openssl enc -e -aes-256-cbc -in file -out file.encoded
openssl enc -e -aes-256-cbc -in file -out file.encoded

После ввода команды, она запросит у вас пароль.
Ключи:
enc – говорит утилите, что шифруем с помощью алгоритма (AES256)
-e – указывает шифровать
-in – входящий файл
-out – выходящий, зашифрованный файл

Можно указать пароль уже внутри команды:

openssl enc -e -aes-256-cbc -k password -in file -out file.encoded
openssl enc -e -aes-256-cbc -k password -in file -out file.encoded

Ключи:
-k password – указываем пароль
Этот метод может быть не надежным, с точки зрения видимости пароля на экране, если у вас стоят за спиной, пароль им будет известен.

Для дешифрования полученного файла ile.encoded:

openssl enc -d -aes-256-cbc -in file.encoded -out file_decrypto
openssl enc -d -aes-256-cbc -in file.encoded -out file_decrypto

Ключи:
-d – ключ указывает на дешифровку

В данном простом примере, мы шифровали одиночный файл, он может быть текстовый, бинарный, какой угодно. Используя архиваторы, мы можем шифровать директории, т.е. натравить архиватор на директорию, завернуть ее, и через конвеер скормить архив утилите openssl, которая его зашифрует:

tar czf - ./test_dir/ | openssl enc -e -aes-256-cbc > archive.tar.gz.encoded
tar czf - ./test_dir/ | openssl enc -e -aes-256-cbc > archive.tar.gz.encoded

И в обратном порядке, для расшифровки:

openssl enc -d -aes-256-cbc -in ./archive.tar.gz.encoded | tar -xz 
openssl enc -d -aes-256-cbc -in ./archive.tar.gz.encoded | tar -xz 

Однако можно поступить и по другому, в Linux файлом может быть контейнер, именно так мы шифровали с помощью GnuPG и Truecrypt, тут все просто. Действуем так, создаем контейнер размером 1Гб, делаем для него файловую систему Ext4, монтируем в систему, записываем файлы, отмонтируем и шифруем его. Поехали:
Создаем контейнер размером 1Gb:

dd if=/dev/zero of=/home/user/test/secret bs=1024 count=1M
dd if=/dev/zero of=/home/user/test/secret bs=1024 count=1M

Получаем файл secret размером 1G
Ключи:
– bs (block size) – размер блока
– count– количество блоков (тут можно использовать шаблоны для простоты)

Создаем для него файловую систему:

mkfs.ext4 -F -b 1024 -L secret ./secret
mkfs.ext4 -F -b 1024 -L secret ./secret

Ключи:
-F (force) – форсировать
-b – размер блоков
-L (label) – метка тома

Монтируем контейнер в систему:

sudo mkdir /mnt/For_temp/
sudo mount -o loop secret /mnt/For_temp/ 
cd /mnt/For_temp/
sudo mkdir /mnt/For_temp/
sudo mount -o loop secret /mnt/For_temp/ 
cd /mnt/For_temp/

Проверить результат:

pwd 
user@userlinux:/mnt/For_temp$ pwd
/mnt/For_temp
 
df -h
/dev/loop0           1008M   35M  922M   4% /mnt/For_temp
pwd 
[email protected]:/mnt/For_temp$ pwd
/mnt/For_temp

df -h
/dev/loop0           1008M   35M  922M   4% /mnt/For_temp

Теперь переместите внутрь файлы которые вы хотите зашифровать и отмонтируйте контейнер:

sudo umount /mnt/For_temp/
sudo umount /mnt/For_temp/

И теперь шифруем его как файл:

openssl enc -e -aes-256-cbc -in secret -out secret.encoded
openssl enc -e -aes-256-cbc -in secret -out secret.encoded

Такой метод мне больше по душе, я не могу утверждать, что он более правильный или менее правильный, но тот, что такие программы как Truecrypt работают по аналогичному механизму показывает, что метод вполне приемлемый и главное надежный.

Недостаток шифрования контейнера с помощью OpenSSL только один, готовый зашифрованный файл выходит точно такого же размера, как и начальный контейнер. Вот для примера:

user@userlinux:~/test$ ls -laSh
-rw-r--r--  1 booch booch 1,1G 2010-11-25 12:13 secret.encoded 
-rw-r--r--  1 booch booch 1,0G 2010-11-25 12:12 secret
[email protected]:~/test$ ls -laSh
-rw-r--r--  1 booch booch 1,1G 2010-11-25 12:13 secret.encoded 
-rw-r--r--  1 booch booch 1,0G 2010-11-25 12:12 secret

Тогда как, если я зашифрую этот же контейнер с помощью GnuPG получим следующее:

user@userlinux:~/test$ ls -laSh
-rw-r--r--  1 booch booch 1,0G 2010-11-25 12:12 secret
-rw-r--r--  1 booch booch 1,1M 2010-11-25 12:20 secret.gpg
[email protected]:~/test$ ls -laSh
-rw-r--r--  1 booch booch 1,0G 2010-11-25 12:12 secret
-rw-r--r--  1 booch booch 1,1M 2010-11-25 12:20 secret.gpg

Как видите из полученного примера, GnuPG обеспечил нам сжатие, и контейнер размером 1G теперь может уместиться на Floppy дискете, при этом когда вы расшифруете контейнер и примонтируете, он будет размером ровно 1G. А OpenSSL сжал наш контейнер с 1G до 1,1G, что не очень удобно, так как “таскать” столь тяжелый файл накладно.