Files
android-encrypted-archiver/README_ru.md
2026-02-25 02:50:47 +03:00

10 KiB
Raw Permalink Blame History

encrypted_archive

Собственный формат зашифрованного архива, неопознаваемый стандартными инструментами анализа (file, binwalk, strings, hex-редакторы).

Возможности

  • AES-256-CBC шифрование с уникальным случайным IV для каждого файла
  • HMAC-SHA-256 аутентификация (IV || шифротекст)
  • GZIP-сжатие с интеллектуальным определением (пропускает уже сжатые форматы)
  • XOR-обфускация заголовка — нет узнаваемых magic bytes
  • Зашифрованная таблица файлов — метаданные невидимы в hex-дампе
  • Обманные вставки (decoy padding) — случайные 644096 байт между блоками данных
  • Три декодера: 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(открытый текст))
│  Обманная вставка (случайная)│  644096 случайных байт
├──────────────────────────────┤
│  Блок данных 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