Прежде всего, я не уверен, что то, что вы пытаетесь сделать, является хорошей идеей.
Имейте в виду, что если вы собираетесь настроить 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);
Надеюсь, это поможет!