Как войти в Apple ID в Xcode через командную строку? - PullRequest
0 голосов
/ 20 февраля 2019

Я унаследовал установку XCode, которая создает приложение для iOS, которое использует автоматическую подпись для сборок разработки.Теперь у меня есть задача создать некоторые настройки CI для этого проекта, но без изменения реального проекта Xcode .Это означает, что я не могу сейчас переключиться на ручную подпись.

Поскольку проект строится нормально локально, я не ожидал, что это будет большой проблемой, но получается автоматическая подпись (очевидно, задним числом)) необходимо, чтобы ваш Xcode был подписан в Apple ID (Xcode => Preferences => Accounts), который должен использоваться для автоматического создания сертификатов.

Есть ли способ добавить Apple ID в Xcode через командную строку?


Это то, что я уже сделал:

Я уже посмотрел вокруг, но не смог найти никаких очевидных ответов через Google.На всех вопросах и ответах здесь, в StackOverflow, всегда упоминается «Просто быстро откройте Xcode и введите свои учетные данные», что, к сожалению, не работает при нашей настройке CI.

Я нашел этот Jenkins «Xcode Plugin» это позволяет вам импортировать .developerprofile, который вы можете экспортировать из XCode.Но моя Java действительно ржавая, и я не мог полностью понять, импортирует ли это «только» профили и удостоверения, или также список учетных записей.

Играя с самим .developerprofile, кажется, он включает информацию об учетной записи (и все сертификаты и т. Д.) В файл .zip, поэтому вы можете извлечь файлы.Это также включает в себя accounts.keychain и accounts.plist, но оба они зашифрованы паролем - который я не знаю, как использовать для получения реальных данных для дальнейшего исследования.

Я также пыталсячтобы узнать, где Xcode первоначально сохраняет информацию, если вы добавляете новый Apple ID: кажется, что имена учетных записей, пароли и некоторые токены помещаются в вашу цепочку ключей «login» (com.apple.gs.xcode.auth.com.apple.account.AppleIDAuthentication.token) и «iCloud» (Xcode-AlternateDSIDXcode-Token).Я также не мог воссоздать существующие записи в доступе Цепочки для ключей вручную, так как «Контроль доступа» -> «Группа доступа для этого элемента:» всегда отличался при создании пароля приложения вручную.Копирование элементов в новую цепочку ключей для экспорта также не сработало, поскольку цепочка для ключей iCloud не позволяет мне копировать материал на новую (даже после отключения синхронизации цепочки для ключей в iCloud, поэтому цепочка для ключей называется «локальной»).элементы ").

1 Ответ

0 голосов
/ 28 мая 2019

Прежде всего, я не уверен, что то, что вы пытаетесь сделать, является хорошей идеей.

Имейте в виду, что если вы собираетесь настроить XCode для автоматического запроса сертификатов разработчика iOS для каждой сборки , и эта сборка выполняется на разных компьютерах (например, размещенный CI, такой как Travis илиAzure Pipelines), ваш сертификат разработчика iOS будет аннулироваться и восстанавливаться каждый раз .

Гораздо лучшим вариантом (на мой взгляд) является экспорт сертификатов разработки iOS и профилей обеспечения через вашего разработчика.профиль и импортируйте сертификат разработки и профиль обеспечения в свою среду сборки.Затем, если необходимо, обновите свой проект XCode, чтобы использовать только что импортированный сертификат и профиль.

Я думаю, что Fastlane уже может сделать почти все это.Если вы ищете вдохновение, у Azure Pipelines есть аналогичная функциональность.Задача, которая устанавливает профиль обеспечения , задача, которая устанавливает сертификат , и задача, которая создает проект Xcode и позволяет вам переопределить сертификат и профили предоставления, используемые при подписанииваш продукт .


Сказав это, accounts.plist и accounts.keychain, вероятно, содержат информацию, которую вы ищете.Оба файла зашифрованы с использованием шифрования AES.

Ключ, используемый для шифрования файла, извлекается из пароля с использованием PBKDF2 (Функция получения ключа на основе пароля 2) с использованием следующих параметров:

  • Функция хеширования: SHA256
  • Пароль: Ваш пароль
  • Salt: байтовое представление вашего пароля с использованием UTF8-кодировки
  • Количество итераций хеширования: 33333
  • Длина ключа: 10

«Магические числа» - это значения по умолчанию, используемые функцией Apple SecKeyDeriveFromPassword, , как описано здесь и , реализованные здесь

Получив ключ шифрования, вы можете расшифровать файл.Вам понадобится вектор инициализации (IV), который опять-таки является значением по умолчанию, используемым Apple - 16-байтовый массив, состоящий полностью из нулей.

В C вы должны иметь возможность использовать такой код, как этотдля генерации ключа шифрования:

CFStringRef password = CFSTR("verysecretstuff");
const char* saltBytes = CFStringGetCStringPtr(password, kCFStringEncodingUTF8);
CFDataRef salt = CFDataCreate(NULL, saltBytes, CFStringGetLength(password));

int keySizeInBits = kSecAES128;
CFNumberRef keySize = CFNumberCreate(NULL, kCFNumberIntType, &keySizeInBits);

int rounds = 33333;
CFNumberRef numberOfRounds = CFNumberCreate(NULL, kCFNumberIntType, &rounds);

CFMutableDictionaryRef parameters = CFDictionaryCreateMutable(NULL, 3, NULL, NULL);
CFDictionaryAddValue(parameters, kSecAttrKeyType, kSecAttrKeyTypeAES);
CFDictionaryAddValue(parameters, kSecAttrKeySizeInBits, keySize);
CFDictionaryAddValue(parameters, kSecAttrPRF, kSecAttrPRFHmacAlgSHA256);
CFDictionaryAddValue(parameters, kSecAttrRounds, numberOfRounds);
CFDictionaryAddValue(parameters, kSecAttrSalt, salt);

CFErrorRef error = NULL;
SecKeyRef key = SecKeyDeriveFromPassword(password, parameters, &error);

Чтобы расшифровать данные, используйте:

const UInt *bytes = NULL; // Encrypted data
CFDataRef data = CFDataCreate(NULL, bytes, length);

CFErrorRef error = NULL;
SecTransformRef transform = SecDecryptTransformCreate(key, &error);
if ( transform == NULL )
{
    CFShow(error);
    CFRelease(error);
}

SecTransformSetAttribute(transform, kSecEncryptionMode, kSecModeCBCKey, &error);
SecTransformSetAttribute(transform, kSecPaddingKey, kSecPaddingPKCS7Key, &error);
SecTransformSetAttribute(transform, kSecTransformInputAttributeName, data, &error);
CFDataRef result = SecTransformExecute(transform, &error);

CFShow(result);

CFRelease(result);
CFRelease(data);
CFRelease(transform);

Надеюсь, это поможет!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...