Миграция сертификатов iOS: чек-лист для Mac

Миграция сертификатов iOS: чек-лист для Mac

Импортировали сертификат, но Xcode по-прежнему сообщает, что приватный ключ не найден.

Самое быстрое решение: перенесите подписывающую идентичность целиком в защищённом формате или создайте новый сертификат на новом Mac, затем проверьте App ID, Provisioning Profile, entitlements, Release Archive и загрузку в App Store Connect. Старый Mac не отключайте, пока новая среда не пройдёт полный тест публикации.

Эта инструкция предназначена для независимых разработчиков, которые переносят сборку на новый или удалённый Mac. Она также пригодится небольшой команде с постоянным iOS-сборочным сервером и тем, чей старый Mac уже повреждён или недоступен.

Сначала сравните способ миграции и критерий готовности

Миграция сертификатов iOS зависит не от самого файла сертификата, а от того, где находится соответствующий приватный ключ и как проект получает права на подпись. Apple прямо разделяет сертификат, ключ и подписывающую идентичность: для подписи кода нужны сертификат и соответствующий ему приватный ключ. Один файл .cer содержит открытые данные и не восстанавливает возможность подписывать приложение. (developer.apple.com)

Перед началом зафиксируйте исходное состояние проекта:

  • Team ID;
  • Bundle ID каждого приложения, расширения и вспомогательной цели;
  • включённые Capabilities;
  • тип сертификата, например Apple Development или Apple Distribution;
  • используемый Provisioning Profile;
  • способ подписи — автоматический, ручной или управляемый скриптами;
  • способ загрузки — Xcode, Transporter, xcrun или API-ключ App Store Connect;
  • имя пользователя, от которого запускается автоматическая сборка;
  • путь к архивам, логам и артефактам.

Не смешивайте три разных режима. При автоматической подписи Xcode может самостоятельно управлять профилями. При ручной подписи проект явно ссылается на сертификат, профиль и entitlements. В автоматизированном процессе часть настроек может находиться в конфигурационных файлах, секрет-хранилище или переменных окружения.

Что проверяется Перенос готовой идентичности Создание нового сертификата
Доступ к старому Mac Нужен Не обязателен
Приватный ключ Переносится вместе с сертификатом Создаётся заново на новом Mac
Provisioning Profile Обычно можно перенести, но нужно проверить соответствие Часто требуется обновить или создать заново
Риск остановки сборки Ниже при сохранённом старом окружении Выше до завершения перевыпуска
Когда выбирать Старый Mac доступен и ключ можно экспортировать Старый Mac утрачен или ключ повреждён
Оценка для плановой миграции 5/5 3/5
Оценка после потери старого Mac Неприменимо 4/5

Критерий готовности должен быть операционным: не «сертификат отображается в Xcode», а «реальный проект собирается в Release Archive, проходит проверку подписи, экспортируется и принимается App Store Connect».

Подготовьте старый Mac, пока он ещё доступен

Начинайте с инвентаризации, а не с удаления старых сертификатов. Если старый Mac ещё работает, сохраните его как резервную среду и не отзывайте сертификаты только потому, что появился новый компьютер.

Откройте Keychain Access и найдите сертификат в разделе пользовательских сертификатов. У подписывающей идентичности должен раскрываться связанный приватный ключ. Если виден только сертификат, это не готовая идентичность для переноса. Apple указывает, что сертификат соответствует одному приватному ключу, а идентичность хранит их вместе в связке ключей. (developer.apple.com)

Для каждого рабочего сертификата зафиксируйте:

  • точное имя идентичности;
  • назначение — разработка, распространение или иной сценарий;
  • команду и Team ID;
  • дату окончания действия;
  • проекты, которые используют этот сертификат;
  • связанные профили;
  • способ запуска сборки.

Экспортируйте идентичность из Keychain Access в защищённый формат PKCS#12, обычно с расширением .p12. Установите отдельный пароль экспорта, не совпадающий с паролем учётной записи Apple. Файл не должен попадать в Git, архив проекта, публичное облачное хранилище или тикет поддержки.

Дополнительно сохраните Provisioning Profile с расширением .mobileprovision или .provisionprofile, но воспринимайте его как отдельный актив. Профиль не заменяет приватный ключ и не исправляет его отсутствие. Apple описывает профиль как объект, который связывает App ID и сертификат распространения; для профиля App Store Connect используется один сертификат распространения. (developer.apple.com)

Сделайте отдельную копию:

  • настроек Signing & Capabilities;
  • файлов конфигурации сборки;
  • скриптов fastlane или shell;
  • переменных окружения без раскрытия секретов;
  • идентификаторов API-ключей;
  • списка entitlements;
  • обезличенных логов последней успешной сборки.

Важно: сертификат подписи, приватный ключ, пароль .p12, ключ App Store Connect API и ключ APNs решают разные задачи. Не объединяйте их в один архив и не передавайте команде больше прав, чем требуется для конкретного этапа.

Почему импорт сертификата не восстанавливает подпись

Если после импорта Xcode показывает ошибку о недостаточном доступе к приватному ключу, обычно произошла одна из трёх ситуаций.

Первая — на новый Mac перенесли .cer, но не .p12. Открытый сертификат сообщает системе, какой публичный ключ связан с разработчиком, однако подписывание выполняется приватным ключом. Вторая — .p12 импортирован не в ту связку ключей или импорт завершился без нужного пароля. Третья — приватный ключ присутствует, но пользователь сборки не может обратиться к нему в режиме без присмотра.

Проверьте новую среду последовательно:

  • в Keychain Access сертификат раскрывается вместе с приватным ключом;
  • импортированная идентичность находится в связке ключей пользователя сборки;
  • команда security find-identity -p codesigning видит ожидаемую идентичность;
  • Xcode показывает правильную команду и Bundle ID;
  • проект не ссылается на старое имя профиля или другой Team ID;
  • при запуске из CI-процесса используется тот же пользователь, которому принадлежит ключ.

Не пытайтесь исправить проблему многократным импортом одного и того же .cer. Это не создаёт приватный ключ. Если идентичность не экспортировали со старого Mac, переходите к перевыпуску сертификата.

Если старый Mac не включается, разделите восстановление и перевыпуск

При полностью недоступном старом Mac нельзя извлечь приватный ключ из публичного сертификата. Публичный сертификат не является резервной копией подписывающей идентичности. Apple описывает приватный ключ как часть криптографической пары, которая создаётся на компьютере или в управляемой инфраструктуре и должна сохраняться отдельно. (developer.apple.com)

Действуйте по ветке условий:

  • Если есть резервная копия связки ключей или защищённый .p12, импортируйте его на новый Mac и переходите к проверке профилей.
  • Если есть только .cer, создайте новый CSR и новый сертификат с правами вашей роли, затем обновите связанные профили.
  • Если сертификат был отозван, пересоздайте Provisioning Profile, потому что профиль, содержащий отозванный сертификат, становится недействительным. (developer.apple.com)
  • Если старый сертификат ещё действует, но приватный ключ потерян, не отзывайте его до появления рабочей замены на новом Mac.
  • Если потерян ключ App Store Connect API, создайте новый ключ в разрешённой роли и обновите секреты автоматизации. Такой приватный ключ после создания не хранится в аккаунте для повторной загрузки, поэтому его нужно сохранить сразу в защищённом месте. (developer.apple.com)

Отзыв — это не обычная уборка. Он может мгновенно нарушить работу профилей и сборочных задач. Сначала создайте замену, подключите её к проекту, выполните Archive и загрузку, а уже потом решайте, нужно ли отзывать старый сертификат.

Перенесите профиль, App ID и права проекта как связку

На новом Mac импортируйте .p12 в ту связку ключей, из которой запускается сборка. После этого установите профиль и откройте проект в Xcode.

Проверка должна идти от идентификатора приложения к подписи:

  • Bundle ID проекта совпадает с зарегистрированным App ID;
  • у основного приложения и расширений нет случайно изменённых идентификаторов;
  • включённые Capabilities совпадают с теми, для которых выпущен профиль;
  • выбран правильный Team;
  • тип профиля соответствует операции — разработка, тестирование или App Store Connect;
  • сертификат в профиле соответствует импортированной идентичности;
  • entitlements в архиве не шире и не уже ожидаемого набора.

Если профиль устарел после изменения сервиса приложения или истёк, его нужно регенерировать. Apple также отмечает, что Xcode может автоматически запросить новый профиль, когда локальный кеш не содержит подходящего варианта; каталог кеша находится в ~/Library/MobileDevice/Provisioning Profiles/. (developer.apple.com)

При ручной подписи скачайте новый профиль из Developer Account и установите его на Mac. При автоматической подписи сначала убедитесь, что у пользователя есть право выполнить нужное действие. Создание распределительных сертификатов и управление некоторыми ресурсами требует роли Account Holder или Admin, тогда как загрузка сборки в App Store Connect доступна, в частности, ролям Account Holder, Admin, App Manager и Developer. (developer.apple.com)

Проведите первую сборку не по частям, а по всей цепочке

Не объявляйте миграцию завершённой после успешной компиляции. Выполните чистую Release-сборку реального проекта и сохраните результат каждого этапа.

Порядок проверки:

  1. Обновите зависимости в заранее зафиксированной версии. Не меняйте одновременно Xcode, SDK, плагины и подпись — иначе причина ошибки будет неочевидна.
  2. Удалите старые Derived Data только после сохранения логов предыдущей успешной сборки.
  3. Выполните Archive для нужной схемы и конфигурации Release.
  4. В архиве проверьте Team ID, Bundle ID, профиль, сертификат и entitlements.
  5. Экспортируйте IPA или другой ожидаемый артефакт тем способом, который используется в рабочем процессе.
  6. Выполните локальную проверку подписи командой codesign или средствами Xcode.
  7. Запустите загрузку в App Store Connect через согласованный инструмент.
  8. Дождитесь обработки сборки и убедитесь, что она появилась в аккаунте и доступна для выбора в версии приложения.

Apple указывает, что после загрузки сборка должна пройти обработку в системе, прежде чем появиться в App Store Connect. Локально созданный IPA поэтому ещё не доказывает успешную публикацию. В 2026 году для загрузки приложений в App Store Connect требуется Xcode 14 или новее; конкретную совместимость проекта с используемой версией Xcode следует отдельно проверить перед миграцией. (developer.apple.com)

Храните лог, но удаляйте из него пароли, токены, пути с именами пользователей и содержимое секретных переменных. В отчёте оставьте:

  • время запуска;
  • схему и конфигурацию;
  • хеш коммита;
  • выбранную подписывающую идентичность без приватных данных;
  • название профиля;
  • статус Archive;
  • статус экспорта;
  • идентификатор загруженной сборки;
  • итог обработки в App Store Connect.

Повторите тест без интерактивного входа

Для постоянного iOS-сборочного сервера одной ручной успешной сборки мало. Перезапустите задачу от имени того же пользователя, который будет работать ночью или после сбоя.

Проверьте:

  • может ли процесс разблокировать нужную связку ключей без отключения защиты;
  • доступен ли приватный ключ после перезагрузки;
  • восстанавливаются ли зависимости;
  • доступны ли переменные окружения;
  • не требует ли Xcode повторного входа в графическом интерфейсе;
  • сохраняется ли доступ к профилю;
  • создаётся ли Archive в чистом рабочем каталоге;
  • выполняется ли загрузка в App Store Connect;
  • можно ли отличить ошибку подписи от ошибки сети или аккаунта.

Не превращайте автоматизацию в обход защиты. Не храните пароль .p12 в открытом скрипте и не делайте связку ключей полностью незащищённой ради того, чтобы ночная задача «просто проходила». Для удалённого Mac заранее определите, кто имеет административный доступ, где лежат резервные копии и как быстро отозвать скомпрометированные ключи.

Если ваш процесс включает несколько приложений, повторите проверку для каждой комбинации Bundle ID, расширения и профиля. Успешная подпись основного приложения не означает, что виджет, уведомления или share extension используют корректные entitlements.

Отключайте старый Mac только после двух подтверждений

Первое подтверждение — новая машина собрала настоящий Release Archive и подписала его ожидаемой идентичностью. Второе — загруженная сборка обработана в App Store Connect и может быть выбрана для версии приложения. Apple позволяет загружать сборки разными инструментами, включая Xcode, Transporter и API-сценарии; метод загрузки должен совпадать с тем, который вы планируете использовать дальше. (developer.apple.com)

После этого выполните контрольный запуск по расписанию. Только если он также завершился успешно, можно:

  • удалить чувствительные файлы со старого Mac;
  • отозвать больше не нужные сертификаты;
  • пересоздать профили, привязанные к старой идентичности;
  • обновить документацию восстановления;
  • определить срок хранения нового удалённого Mac;
  • оставить аварийный архив идентичности в защищённом хранилище.

Если старый Mac уже простаивает, что выбрать

  • Если он ещё доступен и на нём есть приватный ключ, выберите перенос готовой идентичности.
  • Если доступ есть, но автоматизация использует другой аккаунт, сначала исправьте права пользователя сборки.
  • Если старый компьютер скоро отключат, временно держите оба окружения и проведите двойной выпуск.
  • Если старый Mac сломан, перевыпустите сертификат и обновите профили, не пытаясь восстановить ключ из .cer.
  • Если требуется временная замена без покупки оборудования, рассмотрите удалённый Mac для сборочных задач.
  • Если нужна постоянная отдельная машина, сравните bare-metal Mac и виртуализацию macOS до переноса секретов.
  • Если вы строите окружение без локального компьютера, сначала проверьте рекомендации по созданию удалённой среды для macOS.

Главный показатель миграции сертификатов iOS — не наличие файлов на новом Mac, а повторяемый выпуск. Вы должны уметь показать, какой приватный ключ использован, какой профиль разрешает подпись, какие entitlements вошли в архив и что App Store Connect принял именно эту сборку.

Если старый Mac уже нужно вывести из эксплуатации, разумный путь — взять у MacDate удалённый Mac на короткий срок, перенести защищённую идентичность или перевыпустить её, а затем провести настоящий выпуск и повторную автоматическую сборку. Такой подход позволяет проверить подпись и загрузку до принятия решения о постоянной аренде. Покупка собственного Mac лучше подходит для длительной стабильной нагрузки и сценариев с физическими устройствами; удалённый вариант удобнее, когда нужно быстро заменить неисправную машину, провести миграцию или сохранить отдельный Mac как постоянно доступный сборочный сервер.