При попытке собрать релизный APK через Build → Generate Signed Bundle / APK Android Studio требует файл хранилища ключей — keystore, и без него сборка останавливается на первом же шаге мастера. Именно на этом этапе чаще всего застревают начинающие разработчики: debug-сборка устанавливается на устройство без проблем, но для публикации в Google Play или распространения файла напрямую нужна полноценная цифровая подпись.
Подпись APK подтверждает авторство приложения и гарантирует целостность пакета: Android откажется устанавливать обновление, если сертификат новой версии не совпадает с сертификатом уже установленной. Ниже разберём весь процесс — от создания keystore до проверки подписи готового файла, а также типичные ошибки, из-за которых подписанная сборка не собирается.
Зачем нужна подпись APK и какие схемы существуют
Каждое Android-приложение должно быть подписано цифровым сертификатом. При отладочной сборке Android Studio автоматически использует debug keystore, который генерируется при первом запуске IDE. Такой ключ подходит только для локального тестирования: он небезопасен и не принимается магазинами приложений.
Для релиза используется собственное хранилище ключей — файл с расширением .jks или .keystore. Внутри него лежит пара ключей и сертификат разработчика. Важно понимать: потерянный keystore без возможности восстановления означает, что обновлять опубликованное приложение старой подписью больше нельзя — придётся публиковать его заново как новое приложение, если не подключён Play App Signing.
Android поддерживает несколько схем подписи, которые различаются механизмом проверки:
- 🔑 v1 (JAR signing) — классическая схема, совместимая со старыми версиями Android;
- 🔐 v2 (APK Signature Scheme v2) — подписывает файл целиком, быстрее проверяется при установке;
- 🛡️ v3 — добавляет поддержку ротации ключей;
- 📦 v4 — используется для инкрементальной установки, обычно применяется вместе с AAB.
При генерации подписанного APK в современных версиях Android Studio можно отметить сразу несколько схем — это стандартная практика, обеспечивающая совместимость с разными версиями системы.
Создание keystore-файла
Откройте проект и перейдите в меню Build → Generate Signed Bundle / APK. В появившемся окне выберите вариант APK и нажмите Next. На следующем экране мастер предложит указать существующее хранилище или создать новое — нажмите кнопку Create new....
В форме создания хранилища нужно заполнить несколько полей: путь и имя файла keystore, пароль хранилища, алиас ключа и пароль ключа, срок действия сертификата, а также данные владельца (имя, организация, страна). Пароли хранилища и ключа могут совпадать — это упрощает управление, хотя с точки зрения безопасности разные пароли предпочтительнее.
☑️ Перед созданием keystore проверьте
⚠️ Внимание: файл keystore и пароли к нему нельзя коммитить в публичный репозиторий. Утечка ключа позволит злоумышленнику выпускать поддельные обновления от вашего имени. Добавьте файл в .gitignore и храните резервную копию в защищённом месте.
Подпись APK через мастер Android Studio
После создания или выбора keystore мастер попросит ввести пароли от хранилища и ключа. Если данные верны, станет доступен следующий шаг — выбор варианта сборки. Здесь укажите release в качестве Build Variant и отметьте нужные схемы подписи: обычно это V1 и V2 одновременно.
Нажмите Create — Gradle запустит сборку. По завершении в правом нижнем углу появится уведомление со ссылкой locate, которая открывает папку с готовым файлом. Обычно подписанный APK лежит по пути app/release/app-release.apk внутри каталога проекта.
Если сборка завершилась ошибкой, первым делом откройте вкладку Build и прочитайте текст исключения. Частые причины — неверный пароль, конфликт версий Gradle-плагина и ошибки в конфигурации signingConfigs, если она уже частично прописана вручную.
Настройка подписи в build.gradle
Ручной ввод паролей при каждой сборке неудобен, поэтому конфигурацию подписи можно зафиксировать в файле build.gradle уровня модуля. Добавьте блок signingConfigs внутрь секции android и привяжите его к релизному типу сборки:
android {
signingConfigs {
release {
storeFile file("keystore/my-release-key.jks")
storePassword System.getenv("KEYSTORE_PASSWORD")
keyAlias "my-key-alias"
keyPassword System.getenv("KEY_PASSWORD")
}
}
buildTypes {
release {
signingConfig signingConfigs.release
}
}
}
Обратите внимание: пароли в примере берутся из переменных окружения, а не записаны открытым текстом. Это безопасный подход — конфигурацию можно коммитить в репозиторий, не раскрывая секреты. Альтернативный вариант — выносить пароли в файл keystore.properties, исключённый из системы контроля версий.
Проверка подписи готового APK
Перед публикацией или отправкой файла тестировщикам стоит убедиться, что подпись действительно наложена. Для этого используется утилита apksigner, входящая в состав Android SDK Build-Tools. Команда проверки выглядит так:
apksigner verify --print-certs app-release.apk
В выводе отобразятся отпечатки сертификата (SHA-256 и другие) и список задействованных схем подписи. Если команда сообщает, что файл не подписан, значит, сборка прошла в debug-режиме или конфигурация подписи не применилась — вернитесь к настройкам build.gradle.
Дополнительно полезно сравнить отпечаток сертификата с тем, что указан в консоли Google Play, если приложение уже опубликовано. Несовпадение отпечатков при обновлении гарантированно приведёт к отклонению загрузки.
Сравнение способов подписи
У каждого метода есть свои сценарии применения. Таблица ниже поможет выбрать подходящий вариант:
| Способ | Сложность | Когда использовать |
|---|---|---|
| Мастер Generate Signed APK | Низкая | Разовые сборки, первые публикации |
| signingConfigs в build.gradle | Средняя | Регулярные релизные сборки из IDE |
| Gradle CLI (assembleRelease) | Средняя | Автоматизация, сборка без GUI |
| apksigner вручную | Выше средней | Подпись уже собранного неподписанного APK |
| CI/CD с секретами | Высокая | Командная разработка, автоматические релизы |
Типичные ошибки и их решения
Одна из самых частых проблем — ошибка Keystore was tampered with, or password was incorrect. Она означает неверный пароль хранилища либо повреждённый файл keystore. Проверьте раскладку клавиатуры при вводе и убедитесь, что файл не был изменён или частично перезаписан при переносе.
Вторая распространённая ситуация — Google Play отклоняет загрузку с сообщением о несовпадении сертификата. Возможная причина: приложение изначально было подписано другим ключом, либо ранее был включён Play App Signing и загрузочный ключ отличается от того, которым вы подписываете файл сейчас. В этом случае нужно использовать именно upload key, указанный в консоли Play.
⚠️ Внимание: если включён Play App Signing, Google хранит основной ключ подписи у себя, а ваш keystore выполняет роль ключа загрузки. Его можно сбросить через поддержку Google Play, но сам процесс занимает время — не удаляйте upload key до подтверждения замены.
Ещё одна ошибка — Failed to read key from keystore при сборке через Gradle. Обычно она возникает, когда алиас ключа в конфигурации не совпадает с реальным алиасом в хранилище. Посмотреть список алиасов можно командой:
keytool -list -v -keystore my-release-key.jks
Что делать, если keystore утерян
Если приложение опубликовано с Play App Signing — запросите сброс upload key через поддержку Google Play и создайте новое хранилище. Если Play App Signing не использовался, обновить существующее приложение не получится: потребуется публикация под новым именем пакета с новым ключом. Именно поэтому резервная копия keystore критически важна.
FAQ: частые вопросы о подписи APK
Чем подпись APK отличается от подписи AAB?
Принцип тот же — используется keystore и приватный ключ. Разница в том, что AAB (Android App Bundle) загружается в Google Play, а финальные APK для устройств генерирует и подписывает сам магазин, если включён Play App Signing.
Можно ли подписать уже готовый APK без Android Studio?
Да. Для этого служит утилита apksigner из состава Android SDK Build-Tools: команда apksigner sign --ks my-key.jks app.apk подписывает существующий файл. Перед подписью схемой v2 и выше файл должен быть выровнен через zipalign.
Какой срок действия сертификата указывать при создании keystore?
Рекомендуется задавать длительный срок — традиционно 25 лет и более (например, 10000 дней). Приложение с истёкшим сертификатом нельзя будет корректно обновлять, поэтому запас по времени критичен.
Безопасно ли хранить пароли в build.gradle?
Нет, открытые пароли в файле проекта — плохая практика, особенно при использовании публичного репозитория. Используйте переменные окружения или отдельный properties-файл, исключённый из системы контроля версий.
Почему debug APK устанавливается, а подписанный release — нет?
Возможная причина — на устройстве уже установлена версия с другой подписью (например, debug-сборка конфликтует с release). Удалите старую версию приложения и повторите установку. Также проверьте, что в APK включена схема подписи, совместимая с версией Android устройства.