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

1 Шифрование файлов с помощью AES в OpenSSL
Рассмотрим как зашифровать и дешифровать текстовый файл алгоритмом с помощью OpenSSL и алгоритма AES-256-CBC.
Можно использовать два подхода: с явным ключом и IV или через пароль с PBKDF2, который автоматически генерирует ключ и вектор инициализации из пароля и случайной соли.
2 Шифрование
Создадим небольшой текстовый файл для последующего шифрования:
❯ echo "Encrypt this message using OpenSSL now" > message.txt
Проверим содержимое файла:
❯ cat message.txt | xxd
00000000: 456e 6372 7970 7420 7468 6973 206d 6573 Encrypt this mes
00000010: 7361 6765 2075 7369 6e67 204f 7065 6e53 sage using OpenS
00000020: 534c 206e 6f77 0a SL now.
Сгенерируем ключ (KEY) и вектор инициализации (IV):
IV=$(openssl rand -hex 16)
KEY=$(openssl rand -hex 32)
❯ echo $KEY $IV
9cfb54c0c2b5dd866ac0c0a7abd6b8c688bdca45c1f3aa132c008c71df4b24c6 30171b9a66eab28b098d4dd19e89ce85
IV (вектор инициализации) - 16 байт для AES-256-CBC.
Ключ - 32 байта для AES-256 (256 бит).
Зашифруем файл с помощью AES-256-CBC, используя заранее сгенерированные ключ и IV:
❯ openssl enc -aes-256-cbc -in message.txt -out message.bin -K $KEY -iv $IV
Посмотрим, что получилось:
❯ cat message.bin | xxd
00000000: e6bb 1d11 a342 c6cf 7060 ab3d bb32 f177 .....B..p`.=.2.w
00000010: ea02 9939 889c 0125 a13e 3f14 5575 55c3 ...9...%.>?.UuU.
00000020: 30f1 69ca 92d7 0204 f6b2 777a 7316 363f 0.i.......wzs.6?
Размер зашифрованного файла кратен 16 байтам (AES-блок).
Сообщение автоматически дополняется с помощью PKCS#7, чтобы последний блок был полным.
3 Дешифрование
Используем те же ключ и IV, что были при шифровании, чтобы восстановить исходное сообщение:
❯ openssl enc -d -aes-256-cbc -in message.bin -out message.dec -K $KEY -iv $IV
❯ cat message.dec | xxd
00000000: 456e 6372 7970 7420 7468 6973 206d 6573 Encrypt this mes
00000010: 7361 6765 2075 7369 6e67 204f 7065 6e53 sage using OpenS
00000020: 534c 206e 6f77 0a SL now.
Файлы message.txt и message.dec идентичны. Значит все работает!
4 Шифрование с паролем (PBKDF2)
Теперь вместо явного указания KEY и IV мы будем использовать читаемый пароль.
OpenSSL с опцией -pbkdf2 сам преобразует пароль в ключ и IV через PBKDF2, используя случайную соль.
Шифруем файл, используя пароль MySecret123.
❯ openssl enc -aes-256-cbc -in message.txt -out message.bin -pass pass:MySecret123 -pbkdf2
Проверяем зашифрованный файл message.bin:
❯ cat message.bin | xxd
00000000: 5361 6c74 6564 5f5f e094 28d7 3836 c966 Salted__..(.86.f
00000010: b25e deb6 fb4b 1e16 e0ce 2b01 d9aa 68eb .^...K....+...h.
00000020: 0e2d ca6f fe3f 47ad c135 379b 7be1 45f9 .-.o.?G..57.{.E.
00000030: 9d48 3557 4813 1a48 0030 991e 7eac dc7a .H5WH..H.0..~..z
Структура файла:
- Первые 8 байт:
Salted__- маркер, который означает, что файл зашифрован с солью. - Следующие 8 байт: случайную соль
0xe09428d73836c966, которая используется вPBKDF2для генерации ключа иIV. - Остальное: зашифрованные данные.
Соль уникальна для каждого шифрования, поэтому даже при одинаковом пароле зашифрованный файл будет другим.
5 Дешифрование с паролем (PBKDF2)
Расшифровываем файл:
❯ openssl enc -d -aes-256-cbc -in message.bin -out message.dec -pass pass:MySecret123 -pbkdf2
Проверяем результат:
❯ cat message.dec | xxd
00000000: 456e 6372 7970 7420 7468 6973 206d 6573 Encrypt this mes
00000010: 7361 6765 2075 7369 6e67 204f 7065 6e53 sage using OpenS
00000020: 534c 206e 6f77 0a SL now.
6 Преобразование пароля в параметры key и iv
Иногда полезно знать точные значения ключа и IV, которые OpenSSL сгенерировал из пароля и соли с помощью PBKDF2.
Это позволяет расшифровывать данные без повторного использования пароля.
Получаем ключ и IV из пароля и конкретной соли:
❯ openssl enc -aes-256-cbc -pass pass:MySecret123 -pbkdf2 -P -S e09428d73836c966
salt=E09428D73836C966
key=F235FFB8CCB67EE4B7862BE9538229F4DF132335F26DE6EEC5602F94F4B8EC13
iv =E3C3C758EE36C702954E9196F24DB962
Сохраняем параметры в переменных окружения для удобства:
❯ KEY=F235FFB8CCB67EE4B7862BE9538229F4DF132335F26DE6EEC5602F94F4B8EC13
❯ IV=E3C3C758EE36C702954E9196F24DB962
Поскольку OpenSSL добавляет в файл первые 16 байт (Salted__ + соль), их нужно пропустить, чтобы расшифровать только зашифрованные данные:
❯ dd if=message.bin bs=1 skip=16 status=none | openssl enc -d -aes-256-cbc -K $KEY -iv $IV | xxd
00000000: 456e 6372 7970 7420 7468 6973 206d 6573 Encrypt this mes
00000010: 7361 6765 2075 7369 6e67 204f 7065 6e53 sage using OpenS
00000020: 534c 206e 6f77 0a SL now.







