Gen Signed APK: генерация подписанного APK для Android

Команда Generate Signed APK в Android Studio завершается ошибкой «Keystore was tampered with, or password was incorrect» — и сборка релизного пакета останавливается ещё до этапа подписи. Такая ситуация почти всегда означает одно из двух: неверный пароль от хранилища ключей или повреждённый файл .jks / .keystore. Проверить это можно до повторной генерации: откройте терминал и выполните keytool -list -v -keystore путь_к_файлу.jks — если утилита запрашивает пароль и выводит список алиасов, хранилище цело, и проблема кроется в опечатке пароля.

Подписанный APK — обязательное условие публикации приложения в Google Play и установки релизной сборки на устройства пользователей. Неподписанный или debug-пакет система Android либо отклонит, либо установит с ограничениями, поэтому разработчику важно понимать весь цикл: от создания keystore до проверки подписи готового файла. Ниже разобран полный процесс генерации подписанного APK, различия схем подписи и типичные ошибки с безопасными способами их диагностики.

Что такое подпись APK и зачем она нужна

Подпись APK — это криптографическое подтверждение авторства приложения. Каждый пакет подписывается закрытым ключом разработчика, а система Android при установке проверяет сертификат. Если подпись отсутствует или не совпадает с ранее установленной версией приложения, обновление будет заблокировано.

Ключ хранится в файле keystore — защищённом паролем контейнере формата JKS или PKCS12. Внутри находится одна или несколько пар ключей, каждая со своим алиасом (alias) и отдельным паролем. Потеря этого файла означает невозможность выпускать обновления под тем же идентификатором приложения — придётся публиковать программу заново с новым именем пакета.

⚠️ Внимание: файл keystore и пароли от него — единственный способ доказать авторство приложения. Сделайте резервную копию хранилища сразу после создания и держите её отдельно от рабочего компьютера. Восстановить утерянный ключ без механизма Play App Signing невозможно.

Создание keystore: первый шаг

Если хранилища ключей ещё нет, его создают прямо из мастера подписи в Android Studio. Откройте меню Build → Generate Signed Bundle / APK, выберите APK и нажмите Create new... под полем выбора keystore. Мастер попросит указать путь к файлу, пароль хранилища, алиас ключа и пароль алиаса, а также срок действия сертификата.

Альтернативный способ — утилита keytool из состава JDK. Команда создания хранилища выглядит так:

keytool -genkey -v -keystore my-release-key.jks -keyalg RSA -keysize 2048 -validity 10000 -alias my-alias

После выполнения команды утилита задаст несколько вопросов (имя, организация, страна) и создаст файл my-release-key.jks в текущей директории. Эти данные попадут в сертификат и будут видны любому, кто изучит подпись APK, поэтому не указывайте лишнюю личную информацию.

  • 🔑 Используйте разные пароли для хранилища и для алиаса — так безопаснее.
  • 📁 Храните keystore вне папки проекта, чтобы случайно не закоммитить его в репозиторий.
  • 🗒️ Запишите алиас и оба пароля в менеджер паролей — мастер подписи их не восстанавливает.
  • ⏳ Выбирайте срок действия сертификата с запасом: обновления приложения требуют той же подписи.

Пошаговая генерация подписанного APK в Android Studio

Когда хранилище готово, переходите к самой сборке. Последовательность действий в актуальных версиях Android Studio стабильна, хотя названия отдельных кнопок могут немного отличаться между версиями среды.

  • 🛠️ Откройте Build → Generate Signed Bundle / APK и выберите вариант APK.
  • 📂 Укажите путь к файлу keystore, введите пароль хранилища, выберите алиас и введите пароль ключа.
  • ⚙️ Выберите вариант сборки release — debug-сборки подписываются отладочным ключом и не подходят для публикации.
  • ✅ Отметьте схемы подписи (подробнее о них — в следующем разделе) и нажмите Finish.

Готовый файл появится в каталоге app/release/ внутри проекта, а среда покажет уведомление со ссылкой locate для быстрого перехода к нему. Перед загрузкой в консоль разработчика имеет смысл проверить подпись — об этом ниже.

☑️ Проверка перед генерацией релизного APK

Выполнено: 0 / 5

Схемы подписи V1, V2 и дальше

В мастере подписи предлагается выбор схем: V1 (Jar Signature) и V2 (APK Signature Scheme). Первая — классическая подпись JAR-файла, понятная старым версиям Android. Вторая подписывает весь файл целиком, проверяется быстрее и надёжнее защищает от модификации отдельных частей пакета.

Ориентир простой: если минимальная версия Android вашего приложения — 7.0 (API 24) и выше, достаточно схемы V2. Если нужна поддержка более старых устройств, включайте обе схемы одновременно — это стандартная и безопасная практика, которая не увеличивает размер пакета сколько-нибудь заметно.

СхемаПоддержка AndroidОсобенности
V1 (JAR)Все версииМедленная проверка, подписывает файлы по отдельности
V2Android 7.0+Подпись всего пакета, быстрая проверка целостности
V3Android 9.0+Поддержка ротации ключей подписи
V1 + V2Все версииРекомендуемый универсальный вариант

Проверка подписи готового APK

После сборки убедитесь, что файл действительно подписан нужным ключом. Для этого в составе Android SDK есть утилита apksigner, расположенная в каталоге build-tools соответствующей версии. Команда проверки выглядит так:

apksigner verify --print-certs app-release.apk

В выводе будут отпечатки сертификата (SHA-256 и другие). Сравните их с отпечатками вашего keystore — они должны совпадать. Получить отпечаток хранилища можно командой keytool -list -v -keystore файл.jks.

Если apksigner сообщает, что подпись отсутствует, чаще всего причина в том, что был собран неподписанный вариант (например, через обычный Build APK вместо мастера подписи) или сборка завершилась с ошибкой на этапе подписания, а вы открыли файл из предыдущей попытки.

📊 Как вы обычно подписываете релизные APK?
Через мастер в Android Studio
Через Gradle с signingConfig
Через apksigner вручную
Использую CI/CD сборку

Типичные ошибки и их решения

Самая частая проблема — ошибка «Keystore was tampered with, or password was incorrect». В подавляющем большинстве случаев виноват именно неверный пароль: проверьте раскладку клавиатуры, Caps Lock и лишние пробелы при вставке из буфера обмена. Реже файл действительно повреждён — тогда поможет только резервная копия.

Вторая группа ошибок связана с конфигурацией Gradle. Если вы настраиваете подпись через блок signingConfigs в файле build.gradle, опечатка в пути к keystore или в имени алиаса приведёт к сбою сборки с сообщением о невозможности найти ключ. Проверьте, что пути указаны относительно корректной директории или заданы абсолютно.

⚠️ Внимание: никогда не храните пароли от keystore прямо в файле build.gradle, если проект попадает в систему контроля версий. Используйте переменные окружения или файл gradle.properties, добавленный в .gitignore.

Третья ситуация — конфликт подписей при установке: устройство отказывается обновлять приложение с ошибкой INSTALL_FAILED_UPDATE_INCOMPATIBLE. Это значит, что на устройстве стоит версия, подписанная другим ключом (например, debug-сборка). Решение — удалить старую версию перед установкой новой.

Подпись через Gradle без мастера

В build.gradle уровня модуля добавьте блок signingConfigs с параметрами storeFile, storePassword, keyAlias и keyPassword, затем привяжите его к release-сборке через signingConfig в buildTypes. После этого команда gradlew assembleRelease соберёт уже подписанный APK. Пароли безопаснее передавать через gradle.properties, исключённый из репозитория.

APK или AAB: что выбрать для публикации

В том же мастере предлагается вариант Android App Bundle (AAB) — формат, который Google Play требует для новых приложений. AAB не устанавливается на устройство напрямую: магазин сам генерирует из него оптимизированные APK под конкретную конфигурацию устройства пользователя.

Подписанный APK по-прежнему полезен: для прямой установки на тестовые устройства, распространения вне Google Play и публикации в альтернативных каталогах. Поэтому умение генерировать оба формата остаётся базовым навыком разработчика.

⚠️ Внимание: при публикации AAB в Google Play рассмотрите подключение Play App Signing — сервис хранит финальный ключ подписи у Google, а ваш локальный ключ становится ключом загрузки. Это единственный официальный способ восстановить возможность обновлений при утере локального ключа.

FAQ: частые вопросы о подписи APK

Можно ли подписать APK без Android Studio?

Да. Соберите неподписанный пакет через Gradle, затем подпишите его вручную утилитой apksigner sign --ks файл.jks app-unsigned.apk из состава Android SDK build-tools. Для старых проектов со схемой V1 используется jarsigner из JDK.

Что делать, если keystore утерян?

Без резервной копии обновлять приложение под тем же именем пакета не получится. Если был подключён Play App Signing, можно сбросить ключ загрузки через консоль Google Play. Иначе остаётся только публикация приложения заново с новым ключом и новым идентификатором пакета.

Чем debug-подпись отличается от релизной?

Debug-сборки автоматически подписываются отладочным ключом, который Android Studio генерирует сама и хранит в профиле пользователя. Такой ключ не предназначен для публикации: он общий для всех проектов на машине и не доказывает авторство.

Нужно ли заново создавать keystore для каждого приложения?

Нет, одним ключом можно подписывать сколько угодно приложений — это даже удобно для управления. Но с точки зрения безопасности разделение ключей по проектам снижает риск: компрометация одного keystore не затронет остальные приложения.

Почему Google Play отклоняет загруженный APK?

Частые причины: приложение подписано debug-ключом, не совпадает сертификат с предыдущей версией, не увеличен versionCode или загружен APK вместо требуемого для новых приложений формата AAB. Текст ошибки в консоли обычно прямо указывает на конкретную причину.