10 KiB
encrypted_archive
Собственный формат зашифрованного архива, неопознаваемый стандартными инструментами анализа (file, binwalk, strings, hex-редакторы).
Возможности
- AES-256-CBC шифрование с уникальным случайным IV для каждого файла
- HMAC-SHA-256 аутентификация (IV || шифротекст)
- GZIP-сжатие с интеллектуальным определением (пропускает уже сжатые форматы)
- XOR-обфускация заголовка — нет узнаваемых magic bytes
- Зашифрованная таблица файлов — метаданные невидимы в hex-дампе
- Обманные вставки (decoy padding) — случайные 64–4096 байт между блоками данных
- Три декодера: Rust (нативный CLI), Kotlin (JVM/Android), Shell (POSIX)
Быстрый старт
# Сборка
cargo build --release
# Запаковать файлы в архив
./target/release/encrypted_archive pack file1.txt photo.jpg -o archive.bin
# Просмотреть метаданные (без распаковки)
./target/release/encrypted_archive inspect archive.bin
# Распаковать файлы
./target/release/encrypted_archive unpack archive.bin -o ./output/
Команды CLI
pack — Создание зашифрованного архива
encrypted_archive pack <FILES>... -o <OUTPUT> [--no-compress <PATTERNS>...]
| Аргумент | Описание |
|---|---|
<FILES>... |
Один или несколько файлов для архивации |
-o, --output |
Путь к выходному архиву |
--no-compress |
Не сжимать файлы, соответствующие шаблону (суффикс или точное имя) |
Сжатие применяется автоматически. Уже сжатые форматы (.zip, .gz, .jpg, .png, .mp3, .mp4, .apk и др.) сохраняются без повторной компрессии.
# Упаковка с управлением сжатием
encrypted_archive pack app.apk config.json -o bundle.bin --no-compress "app.apk"
unpack — Распаковка файлов
encrypted_archive unpack <ARCHIVE> [-o <DIR>]
| Аргумент | Описание |
|---|---|
<ARCHIVE> |
Файл архива для распаковки |
-o, --output-dir |
Директория для извлечения (по умолчанию: .) |
inspect — Просмотр метаданных
encrypted_archive inspect <ARCHIVE>
Отображает поля заголовка, количество файлов, размеры, статус сжатия и хэши целостности — без извлечения содержимого.
Декодеры
Архив может быть декодирован тремя независимыми реализациями. Все дают побайтно идентичный результат из одного и того же архива.
Rust (нативный CLI)
Основная реализация. Используется через подкоманду unpack (см. выше).
Kotlin (JVM / Android)
Однофайловый декодер для JVM-окружений. Без внешних зависимостей — использует javax.crypto и java.util.zip из стандартной библиотеки.
Автономное использование:
# Компиляция
kotlinc kotlin/ArchiveDecoder.kt -include-runtime -d ArchiveDecoder.jar
# Декодирование
java -jar ArchiveDecoder.jar archive.bin ./output/
Как библиотека в Android-проекте:
Скопируйте kotlin/ArchiveDecoder.kt в исходники вашего проекта. Все используемые криптографические и компрессионные API (javax.crypto.Cipher, javax.crypto.Mac, java.util.zip.GZIPInputStream) доступны в Android SDK.
Для использования как библиотеки вызывайте логику декодирования напрямую вместо main():
// Пример: декодирование из файла
val archive = File("/path/to/archive.bin")
val outputDir = File("/path/to/output")
decode(archive, outputDir)
// Функция decode() выполняет:
// 1. XOR-деобфускацию заголовка
// 2. Расшифровку таблицы файлов (TOC)
// 3. AES-расшифровку + HMAC-верификацию каждого файла
// 4. GZIP-декомпрессию (если файл сжат)
// 5. Проверку целостности по SHA-256
Нативный .so не требуется — чистый Kotlin/JVM, работает на ART.
Shell (POSIX)
Аварийный декодер для POSIX-систем с установленным OpenSSL.
sh shell/decode.sh archive.bin ./output/
Зависимости: dd, openssl, sha256sum, gunzip и xxd или od.
Важно: Этот декодер требует
opensslдля операций AES и HMAC. Он не будет работать в минимальных окружениях типа BusyBox, где OpenSSL отсутствует. Для ограниченных сред используйте Rust- или Kotlin-декодер.
Спецификация формата
Полная спецификация бинарного формата: docs/FORMAT.md
Структура архива (обзор)
┌──────────────────────────────┐ смещение 0
│ Заголовок (40 байт, XOR) │ magic, версия, флаги, toc_offset, toc_size, toc_iv, кол-во файлов
├──────────────────────────────┤ смещение 40
│ TOC (зашифрован AES-CBC) │ записи файлов: имя, размеры, смещения, IV, HMAC, SHA-256
├──────────────────────────────┤
│ Блок данных 0 │ AES-256-CBC(GZIP(открытый текст))
│ Обманная вставка (случайная)│ 64–4096 случайных байт
├──────────────────────────────┤
│ Блок данных 1 │
│ Обманная вставка (случайная)│
├──────────────────────────────┤
│ ... │
└──────────────────────────────┘
Байт флагов
| Бит | Маска | Функция |
|---|---|---|
| 0 | 0x01 |
Хотя бы один файл GZIP-сжат |
| 1 | 0x02 |
TOC зашифрован AES-256-CBC |
| 2 | 0x04 |
Заголовок XOR-обфусцирован |
| 3 | 0x08 |
Обманные вставки между блоками данных |
Стандартные архивы со всеми функциями: флаги = 0x0F.
Модель безопасности
Что обеспечивается:
- Конфиденциальность — AES-256-CBC шифрование каждого файла
- Целостность — HMAC-SHA-256 для каждого файла (encrypt-then-MAC)
- Верификация содержимого — SHA-256 хэш оригинального открытого текста
- Защита от анализа — никаких узнаваемых паттернов для
file,binwalk,strings
Что НЕ обеспечивается:
- Управление ключами — v1 использует зашитый ключ (v2 будет использовать подключи через HKDF)
- Прямая секретность (forward secrecy)
- Защита от целевого криптоанализа (XOR-ключ фиксирован и публичен)
Слой обфускации рассчитан на противодействие поверхностному анализу, а не целенаправленному исследователю, знакомому с форматом.
Сборка из исходников
# Отладочная сборка
cargo build
# Релизная сборка (оптимизированная)
cargo build --release
# Запуск всех тестов (юнит + интеграция + golden vectors)
cargo test
Кросс-валидационные тесты
# Тесты Kotlin-декодера (требуется kotlinc + java)
bash kotlin/test_decoder.sh
# Тесты Shell-декодера (требуется openssl + sha256sum)
bash shell/test_decoder.sh
Структура проекта
encrypted_archive/
├── src/
│ ├── main.rs # Точка входа CLI
│ ├── cli.rs # Определение аргументов (Clap)
│ ├── archive.rs # Упаковка / распаковка / инспекция
│ ├── format.rs # Сериализация бинарного формата
│ ├── crypto.rs # AES-256-CBC, HMAC-SHA-256, SHA-256
│ ├── compression.rs # GZIP + определение сжатых форматов
│ └── key.rs # Криптографический ключ
├── kotlin/
│ └── ArchiveDecoder.kt # JVM/Android-декодер (один файл)
├── shell/
│ └── decode.sh # POSIX shell-декодер
├── docs/
│ └── FORMAT.md # Спецификация бинарного формата (нормативная)
└── tests/
└── golden_vectors.rs # Тесты с известными ответами
Лицензия
TBD