Шифрование PCK: ключ, шаблоны и фильтры
Один AES-256 ключ для сборки и экспорта, отдельное шифрование файлов и каталога, диагностика ошибок.
Шифрование PCK
Шифрование PCK скрывает содержимое выбранных файлов от простого чтения архива. Оно не делает клиентскую игру хранилищем секретов: ключ для расшифрования присутствует в исполняемой сборке. Внешние DLL и другие файлы вне PCK этим способом не шифруются.
Нужны один и тот же 32-байтовый ключ для упаковки и соответствующего экспортного шаблона, правильный выбор шаблона и фильтров. Ключ записывается как 64 шестнадцатеричные цифры без 0x, пробелов и перевода строки. Случайно выбранный готовый шаблон не получит ваш ключ из переменной окружения во время запуска.
Подготовить ключ
Пример для PowerShell 7: ключ генерируется в памяти, не печатается и передаётся текущим процессам сборки и экспорта. Выполняйте это в отдельной оболочке, подготовленной для сборки под Windows.
$pckKey = [Convert]::ToHexString([Security.Cryptography.RandomNumberGenerator]::GetBytes(32)).ToLowerInvariant()
if ($pckKey -notmatch '^[0-9a-f]{64}$') { throw "Invalid key format" }
$env:SCRIPT_AES256_ENCRYPTION_KEY = $pckKey
$env:RECKFELL_SCRIPT_ENCRYPTION_KEY = $pckKeyДля повторных сборок храните исходный ключ в своём защищённом хранилище и загружайте его в окружение сборочного процесса. Не генерируйте новый ключ при каждом экспорте, оставляя старый шаблон. Не передавайте ключ онлайн-генератору и не записывайте его в опубликованный пример.
| Переменная | Когда читается |
|---|---|
SCRIPT_AES256_ENCRYPTION_KEY | При сборке: встраивается в бинарный файл. |
RECKFELL_SCRIPT_ENCRYPTION_KEY | При экспорте: имеет приоритет над ключом в пресете. Также служит запасным источником для сборки, если первая переменная отсутствует. |
Пустая первая переменная не равна отсутствующей: не оставляйте её пустой, рассчитывая на запасную. Использование обеих переменных с одним значением устраняет эту неоднозначность. Запустите редактор или CLI-экспорт из оболочки с нужным окружением: уже открытый редактор новое окружение не унаследует.
Собрать и выбрать шаблоны
Из корня Source соберите нужные варианты. Например, для нативного Windows x64 проекта:
scons platform=windows target=template_debug arch=x86_64
scons platform=windows target=template_release arch=x86_64Для C# нужны также module_mono_enabled=yes и соответствующий комплект управляемых сборок: см. сборку с .NET. Не используйте нативный шаблон вместо шаблона с поддержкой C#.
В пресете Windows укажите полученные файлы в custom_template/debug и custom_template/release. Должны совпадать ключ, архитектура, точность и требуемые модули. Release-экспорт выбирает release-шаблон, debug-экспорт — debug-шаблон. Сообщение о заданном ключе во время сборки подтверждает чтение переменной, но не подтверждает запуск будущей игры.
При изменении ключа пересоберите все используемые шаблоны и заново экспортируйте PCK. Не подменяйте установленный рабочий Runtime пробной сборкой.
Настроить пресет экспорта
Откройте настройки шифрования выбранного экспортного пресета:
| Настройка | Действие |
|---|---|
encrypt_pck | Разрешает шифрование выбранных файлов PCK. |
encryption_include_filters | Какие экспортируемые пути шифровать. Для первого полного теста используйте *. Пустой список не выбирает ни одного файла. |
encryption_exclude_filters | Исключения из шифрования; имеют приоритет над включениями. Для первого теста оставьте пустым. |
encrypt_directory | Дополнительно шифрует каталог путей. При экспорте требует включённого encrypt_pck. |
Фильтры проверяются без учёта регистра по экспортируемому пути, с asset:// или без него. Они не определяют состав экспорта: включение ресурса в PCK и выбор его для шифрования — разные действия. Импортированная текстура может экспортироваться под служебным путём, поэтому фильтр только исходных *.png не доказывает шифрование её импортированных данных.
Экспорт использует ключ из непустой RECKFELL_SCRIPT_ENCRYPTION_KEY; иначе — ключ пресета. В текущем редакторе ключ пресета сохраняется в .reckfell/export_credentials.cfg, а обычные настройки — в export_presets.cfg. Не публикуйте файл credentials. Для CI подавайте ключ через окружение до запуска процесса экспорта.
При ручной упаковке через PckPacker выбор независим: PckStart(..., encryptDirectory: true) шифрует каталог, а AddFile(..., encrypt: true) или AddFileFromBuffer(..., encrypt: true) — данные конкретного файла. Один флаг не заменяет другой. Обязательно проверьте результаты PckStart, добавления файлов и Flush.
Проверить результат
- Экспортируйте игру с нужным пресетом и соответствующим шаблоном.
- Запустите экспортированную игру, а не проект через редактор. Откройте уровень, загрузите текстуры, звуки и прочие зашифрованные ресурсы.
- Повторите для каждого реально используемого варианта debug/release. Не переносите результат одной архитектуры или платформы на другую.
- Проверьте, что выбранные данные отсутствуют в PCK как открытый текст, а при шифровании каталога не видны выбранные пути. Одного такого поиска недостаточно для проверки криптографической защиты; он помогает обнаружить выключенный флаг или пустой фильтр.
Для этой статьи на установленном SDK проверены четыре сочетания шифрования файлов/каталога, чтение созданных данных независимым AES-декодером и отказ проверки целостности с неверным тестовым ключом. Новые шаблоны с пользовательским ключом не собирались; полный запуск экспортированной игры здесь не подтверждён.
Если экспорт или загрузка не работает
- Данные видны открыто: проверьте
encrypt_pck, include-фильтры и исключения. Шифрование каталога не шифрует файлы автоматически. - Can't open encrypted pack directory: каталог не расшифровался. Сверьте выбранный шаблон, ключ и целостность PCK.
- MD5 sum of the decrypted file does not match: возможен неверный ключ или повреждённый файл. Это не доказательство только одной причины.
- Редактор читает, игра не читает: чтение инструментом с явно переданным ключом не доказывает, что нужный ключ встроен в экспортный шаблон.
- Работает только debug: проверьте отдельный release-шаблон и его сборочное окружение.
После завершения работы очистите окружение отдельной оболочки. Это не удаляет ключ из уже собранного бинарного файла или сохранённого пресета:
Remove-Item Env:SCRIPT_AES256_ENCRYPTION_KEY -ErrorAction SilentlyContinue
Remove-Item Env:RECKFELL_SCRIPT_ENCRYPTION_KEY -ErrorAction SilentlyContinue
Remove-Variable pckKey -ErrorAction SilentlyContinue