SecItemAdd и SecItemCopyMatching возвращают код ошибки -34018 (errSecMissingEntitlement)

116

Иногда, когда я запускаю приложение на устройстве из Xcode, я пытался получить доступ к связке ключей, но не мог из-за ошибки -34018. Это не соответствует ни одному из документированных кодов ошибок связки ключей и не может быть последовательно воспроизведено. (бывает, может быть, в 30% случаев, и мне непонятно, почему это происходит). Что делает отладку этой проблемы очень сложной, так это полное отсутствие документации. Есть идеи, что вызывает это и как это исправить? Я использую Xcode 5 и использую iOS 7.0.4 на устройстве.

Здесь есть открытая проблема: https://github.com/soffes/sskeychain/issues/52

РЕДАКТИРОВАТЬ: добавление кода доступа к связке ключей по запросу

Я использую SSKeychainбиблиотеку для взаимодействия с связкой ключей. Вот отрывок.

#define SERVICE @"default"

@implementation SSKeychain (EXT)

+ (void)setValue:(NSString *)value forKey:(NSString *)key {
    NSError *error = nil;
    BOOL success = NO;
    if (value) {
        success = [self setPassword:value forService:SERVICE account:key error:&error];
    } else {
        success = [self deletePasswordForService:SERVICE account:key error:&error];
    }
    NSAssert(success, @"Unable to set keychain value %@ for key %@ error %@", value, key, error);
    if (!success) {
        LogError(@"Unable to set value to keychain %@", error);
    }
    LogTrace(@"Will set keychain account %@. is to nil? %d", key, value == nil);
    if (value == nil)
        LogWarn(@"Setting keychain %@ to nil!!!", key);
}

+ (NSString *)valueForKey:(NSString *)key {
    NSError *error = nil;
    NSString *value = [self passwordForService:SERVICE account:key error:&error];
    if (error && error.code != errSecItemNotFound) {
        NSAssert(!error, @"Unable to retrieve keychain value for key %@ error %@", key, error);
        LogError(@"Unable to retrieve keychain value for key %@ error %@", key, error);
    }
    return value;
}

+ (BOOL)removeAllValues {
    LogInfo(@"Completely Reseting Keychain");
    return [[self accountsForService:SERVICE] all:^BOOL(NSDictionary *accountInfo) {
        return [self deletePasswordForService:SERVICE account:accountInfo[@"acct"]];
    }];
}

@end

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

Тони
источник
У меня такая же проблема, и я не могу ее воспроизвести ... Я использую класс KeychainItemWrapper от Apple. Иногда вылетает из Google Analytics с тем же сообщением об ошибке. Я использую Google Analytics v3.02.
Joey
Также вроде нормально в приложении из AppStore. это происходит только в разрабатываемой версии приложения.
Joey
2
У меня есть аварийные сообщения для версии магазина приложений, и, к сожалению, похоже, что это происходит и в магазине приложений, хотя и реже, чем в dev: /
Тони
3
Я думаю о том, чтобы отказаться от связки ключей, потому что тот факт, что данные, хранящиеся в связке ключей, могут быть случайно потеряны, как это в значительной степени фатальная ошибка для приложения.
Тони
2
Мы также наблюдаем эту периодически возникающую проблему. Мы вызываем исключение, когда получаем неожиданное сообщение rc от secItemCopyMatching, включая случай -34018. Мы попытались (неохотно) добавить механизм, в котором, как только мы получаем нужное значение из связки ключей, мы кэшируем его в памяти приложения, а затем обслуживаем оттуда без доступа к связке ключей. Но теперь мы наблюдаем редкие случаи, когда доступ к одной связке ключей, чтобы получить его, в первую очередь не работает с -34018. Кто-нибудь пробовал повторить операцию после -34018?
Крис Маркл

Ответы:

45

Исправление iOS 10 / XCode 8:

Добавьте право на цепочку ключей, перейдите в настройки проекта-> Возможности-> Совместное использование цепочки для ключей-> Добавить группы цепочки для ключей + включить

Ответ здесь от Apple:

ОБНОВЛЕНИЕ: наконец-то мы смогли воспроизвести ошибку -34018 на iOS 8.3. Это первый шаг к определению основной причины и последующему поиску решения.

Как обычно, мы не можем установить сроки выпуска, но это коснулось многих разработчиков, и мы действительно хотим решить эту проблему.

Ранее я предлагал добавить небольшую задержку в application: didFinishLaunchingWithOptions и applicationDidBecomeActive: перед доступом к связке ключей в качестве временного решения. Однако на самом деле это не помогает. Это означает, что на данный момент нет известного обходного пути, кроме перезапуска приложения.

Проблема, по-видимому, связана с нехваткой памяти, поэтому, возможно, более агрессивная обработка предупреждений о памяти может облегчить проблему.

https://forums.developer.apple.com/thread/4743#14441

ОБНОВИТЬ

Хорошо, вот последний.
Это сложная проблема, имеющая несколько возможных причин:

  • Некоторые случаи проблемы вызваны неправильным подписанием приложения. Этот случай легко отличить, потому что проблема воспроизводима на 100%.
  • Некоторые случаи проблемы вызваны ошибкой в ​​том, как iOS поддерживает разработку приложений (около 23 991 853). Отладка этого осложнялась тем фактом, что другая ошибка в ОС (r. 23 770 418) замаскировала ее эффект, а это означает, что проблема возникала только тогда, когда устройство находилось под нехваткой памяти. Мы считаем, что эти проблемы были решены в iOS 9.3.
  • Мы подозреваем, что причин этой проблемы может быть больше.

Итак, если вы видите эту проблему на пользовательском устройстве (с которым не разговаривал Xcode), работающем под управлением iOS 9.3 или более поздней версии, отправьте отчет об ошибке. Попробуйте включить системный журнал устройства в свой отчет об ошибке (я понимаю, что это может быть сложно при работе с пользовательскими устройствами; один из вариантов - попросить клиента установить Apple Configurator, который позволяет им просматривать системный журнал). И если вы все же сообщаете об ошибке, укажите свой номер ошибки для записи.

От имени Apple я хотел бы поблагодарить всех за их усилия по поиску этой довольно ужасной проблемы. Делитесь и наслаждайтесь

https://forums.developer.apple.com/thread/4743#126088

Daidai
источник
2
Проблема все еще воспроизводится на iOS 9.2 и iPhone 5S.
DevGansta
1
Похоже, что iOS 9.3 должна решить эту проблему, согласно последнему ответу Apple в теме, на которую вы указали. @daidai, не могли бы вы обновить свой ответ этой новой информацией?
jf
1
@YoonLee я также вижу это с iOS10 - также с использованием AWS 2.4.8 SDK. Возникла ошибка в строке 54 AWSClientContext.m. Удачи в решении этой проблемы?
CharlesA
1
@YoonLee, кстати, просто решил это, используя один из ответов ниже: «KeyChain Sharing включен для целевых возможностей»
CharlesA
1
@CharlesA Да, я решил в тот день. Ты прав. Кажется, «включение KeyChain Entitlement» решает проблему. Удивительно, но эта ошибка срабатывает не всегда. В любом случае, теперь я включаю это.
Юн Ли
26

По сути, вам нужно закодировать свою папку .xcttest, добавив следующее в качестве сценария запуска в вашу тестовую цель.

codesign --verify --force --sign "$CODE_SIGN_IDENTITY" "$CODESIGNING_FOLDER_PATH"

При тестировании брелка на устройстве у меня было много ошибок -34018, и это удалось исправить.

Если проблема не существует в вашей тестовой цели, это, вероятно, не решение.

JorgeDeCorte
источник
Подтверждено, что это исправлено в тестовой среде. Мне пришлось добавить сценарий запуска на фактическую цель тестирования (например, те, которые содержат все модульные тесты, а не цель сборки, которая выполняется на устройстве). Также подтверждено, что это проблема только на устройстве, а не на симуляторе.
iwasrobled
2
Когда я делаю это, я получаю «: личность не найдена. Команда / bin / sh завершилась неудачно с кодом выхода 1»? Думаю, у меня нет $ CODE_SIGN_IDENTITY. Есть идеи, как это исправить?
Daniel Coffman
1
@DanielCoffman, вы должны перейти к своим целевым настройкам и в поле «Идентификация подписи кода» выбрать «Разработчик iOS» (или любой другой действительный идентификатор). Это исправляет ошибку сборки, но, по крайней мере, для меня это не решает проблему связки ключей. Я все еще получаю код ошибки -34018.
Marcin
3
Спасибо, Марчин. Я начал получать эту ошибку, когда перешел на бета-версию xcode 6. Никакие предложения в этой теме не решены. Вернулся к xcode 5 и -34018 больше не происходит.
Daniel Coffman
Я впервые сталкиваюсь с этой ошибкой с тех пор, как использую XCode 6.3.
Владимир Славик
13

После проверки исходного кода . Я заметил, что доступ к функциям связки ключей осуществляется через демон безопасности, который работает в собственном процессе (отделенном от процесса приложения).

Ваше приложение и защищенный процесс взаимодействуют друг с другом с помощью технологии XPC. .

При необходимости, securityd запускается через известную команду launchd от XPC. Вероятно, вы можете проверить, запущен ли демон в приложении Activity Monitor (если, конечно, он работает в Simulator) и что его родительский процесс запущен.

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

Может быть, вы могли бы подумать, как предварительно запустить демон.

Прошу прощения за неточность. Я надеюсь, что это поможет вам продолжить ваши расследования.

Винсент Згеб
источник
2
У меня возникает эта проблема, только когда мое приложение повторно открывается через глубокую ссылку со следующим методом делегирования приложения: - (BOOL) application: (UIApplication *) application handleOpenURL: (NSURL *) url. Если я просто запускаю приложение, запись в связку ключей работает, а если я минимизирую и увеличиваю приложение, оно все равно работает. Эта проблема возникает только тогда, когда я снова открываюсь с глубокой ссылкой. В моем проекте настроены элементы MyApp.entitlements («Связка ключей» на вкладке «Возможности») Xcode 7 beta 4.
FranticRock
Мой случай похож на случай Алекса, который случается только тогда, когда приложение имеет глубокую ссылку. В противном случае все работает нормально. Может быть, какой-то контекст не подходит, когда приложение открывается из другого приложения.
CodeBrew
12

Я наблюдаю подобное поведение после создания и запуска моего кода в бета-версии Xcode 6 с iOS 8 SDK (он правильно работает с Xcode 5 / iOS 7). В Xcode 6 в симуляторе iOS SecItemCopyMatching всегда возвращает -34018. Он начал работать после включения «Связки ключей» на вкладке «Возможности».

Однако у меня есть другая проблема. Я разрабатываю статическую библиотеку, которая используется (среди прочего) демонстрационным приложением. Вышеупомянутое решение работает для проекта демонстрационного приложения, но когда я пытаюсь выполнить модульное тестирование своего проекта статической библиотеки, у меня возникает точно такая же ошибка. И проблема в том, что в моем проекте статической библиотеки нет вкладки «Возможности» (поскольку это не отдельное приложение).

Я пробовал решение, опубликованное здесь JorgeDeCorte, с кодовой подписью в тестовой цели, но у меня это не работает.

Marcin
источник
8
И снова в iOS 8 beta 3 :)
Мустафа
7
И снова в iOS 9.0
Alex Stone
4
А теперь вернемся в iOS 9.2 :-(
Vamos
4
Снова в iOS 10 beta 2
Пранджал Бикаш Дас
3
И снова в iOS 10 beta 5
Паскаль,
6

Попробуйте отключить все точки останова при запуске приложения из Xcode. Вы можете включить их позже.

(Ни один из вышеперечисленных обходных путей у меня не помог)

HeTzi
источник
Странный. Кажется, эта проблема решена и для меня! Каждый раз, когда я начинал отладку на симуляторе, я мог испытать -34018 OSStatus.
midori
4

У меня была такая же проблема на симуляторе под управлением 7.1 и 8.0. Покопавшись, я заметил, что в примере приложения Apple было включено KeyChain Sharing для его целевых возможностей. Я включил его для своего приложения, что привело к созданию файла прав, который я оставил со значениями по умолчанию, и теперь я больше не получаю ошибок -34018. Это не идеально, но пока я буду жить с опцией обмена KeyChain.

Laurent
источник
4

В некоторых случаях создание пакета .xctest не так просто, как кажется. В принципе JorgeDeCorte правильно его ответ , что данная короткая линия как Run Scriptдостаточно для большинства разработчиков.

codesign --verify --force --sign "$CODE_SIGN_IDENTITY" "$CODESIGNING_FOLDER_PATH"

Но когда у вас есть несколько сертификатов в вашей связке ключей, это не сработает со следующей строкой

iPhone Developer: ambiguous (matches "iPhone Developer: Your Name (ABC123DEF45)" and "iPhone Developer: Your Name (123ABC456DE)"

Этот короткий сценарий поможет вам получить правильный сертификат даже при наличии нескольких сертификатов. Конечно, это не идеально, но, насколько мне известно, у вас нет шансов получить сертификат, который Xcode нашел и использует для подписи вашего .app.

echo "codesign --verify --force --sign \"$CODE_SIGN_IDENTITY\" \"$CODESIGNING_FOLDER_PATH\""
IDENTITIES=`security find-identity -v -s "Code Signing" | grep "iPhone Developer" | awk '{ print $2 }'`

for SHA in $IDENTITIES; do
    codesign --verify --force --sign $SHA "$CODESIGNING_FOLDER_PATH"
    if [ $? -eq 0 ]; then
        echo "Matching identity found: $SHA"
        exit 0
    fi
done;

exit 1
Patrik
источник
4

Меня это тоже укусило, и другие обходные пути не помогли. Затем я очистил свои профили подготовки на самих устройствах, удалив все из них, связанные с моим приложением, а также все профили с подстановочными знаками (похоже, в этом суть). Для этого перейдите в окно «Устройства» в Xcode и щелкните правой кнопкой мыши свой (подключенный) телефон:

Нажмите «Показать профили обеспечения» и удалите связанные профили, особенно профили группы:

в том числе отмеченные звездочкой. После переустановки приложения все вернулось в норму.

k1th
источник
Это помогло мне запустить приложение из Xcode и продолжить процесс разработки.
salabaha
При создании выпуска AdHoc вы можете проверить, какие PP используются. если вы видите какие-либо профили XC:, удалите их и обновите свой PP!
doggod
Я понимаю, как это может быть фактором. Какой там беспорядок !! Делаем уборку после падения
Дэвид
3

Я исправил эту проблему (думаю). У меня был профиль подготовки с подстановочными знаками на моем устройстве, который показал, что у него нет действительной подписи. У меня также был действующий профиль подготовки для моего приложения. Когда я удалил профиль с подстановочными знаками, я перестал получать ошибки -34018.

Я также убедился, что идентификатор подписи кода и профиль обеспечения, перечисленные в разделе «Подписание кода» в настройках сборки целевого объекта, были идентичны таковому для приложения (а не общему «разработчику iPhone»).

Дэйв Хирш
источник
Подобно этому исправил это для меня. Установите для подписи кода на уровне проекта значение «Разработчик iPhone» для отладки и «Распространение iPhone» для выпуска. Затем я удалил переопределения на основной цели, чтобы они отображались одинаково. Раньше сохранение в связке ключей приводило к сбоям в 100% случаев. После этого сохранение в связке ключей работает стабильно.
jowie
2

Я очень редко получал ошибку -34018 в моем приложении (iOS 8.4). После некоторого расследования я обнаружил, что эта проблема возникает, когда приложение слишком часто запрашивает данные из связки ключей .
Например, в моей ситуации это были два запроса на чтение для одного конкретного ключа одновременно из разных модулей приложения.
Чтобы исправить это, я просто добавил кеширование этого значения в памяти

somedev
источник
1

У меня неожиданно возникла та же проблема, запущенная на тестовом устройстве с Xcode 6.2, iPhone 6, iOS 8.3. Чтобы быть ясным, этого не произошло при запуске тестов Xcode, а скорее при запуске реального приложения на моем устройстве. В симуляторе все было хорошо, а в самом приложении до недавнего времени все было отлично.

Я пробовал все предложения, которые мог найти здесь, например, удаление профилей подготовки на моем устройстве (я удалил ВСЕ из них), временное включение возможности совместного использования связки ключей в моем проекте (хотя нам это действительно не нужно), уверен, что моя учетная запись разработки в Xcode была полностью обновлена ​​со всеми сертификатами, профилями обеспечения и т.д. Ничего не помогло.

Затем я временно изменил уровень доступности с kSecAttrAccessibleAfterFirstUnlockна kSecAttrAccessibleAlwaysThisDeviceOnly, запустил приложение, оно работало нормально и смог писать в связку ключей. Затем я снова изменил его на kSecAttrAccessibleAfterFirstUnlock, и проблема, похоже, исчезла "навсегда".

Мейсон Дж. Жвити
источник
1

Только что укусил эту ошибку в Xcode 8 Beta 3. Включение общего доступа к связке ключей кажется единственным решением.

XCool
источник
1

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

lumenela
источник
1

(это не прямой ответ на вопрос OP, но может помочь другим)

После обновления Xcode с версии 7.3.1 до 8.0 в симуляторе постоянно появлялась ошибка связки ключей -34018.

Следуя этому совету из ответа дайдая ,

Некоторые случаи проблемы вызваны неправильным подписанием приложения. Этот случай легко отличить, потому что проблема воспроизводима на 100%.

было обнаружено, что профиль Provisioning Profile каким-то образом был установлен на None в разделах подписи целевого объекта.

Однако установки допустимых значений для полей профиля Provisioning Profile было недостаточно для решения проблемы в этом случае.

Дальнейшее расследование показало, что право на push-уведомления также отображало ошибку. Он сказал: «Добавьте функцию push-уведомлений в свой идентификатор приложения». шаг был завершен, но шаг «Добавить право на push-уведомления в файл полномочий» - нет.

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

Для этой конкретной цели право «Совместное использование связки ключей» уже было включено ранее. Отключение этой функции пока не привело к повторному появлению ошибки связки ключей, поэтому неясно, нужна ли она в данном случае.

jk7
источник
0

В iOS 9 я отключил Address Sanitizer, и он начал работать на устройстве.

pulse4life
источник
0

Единственное решение, которое сработало для меня, - сначала сохранить nil для указанного ключа, а затем сохранить мое новое значение с помощью отдельной операции. Если я попытаюсь перезаписать существующее значение, произойдет сбой из-за ошибки -34018. Но до тех пор, пока я сначала сохранил nil , обновленное значение будет успешно сохранено сразу после этого.

FranticRock
источник
0

Я столкнулся с этой проблемой -34018 сегодня при запуске SecItemDelete API. Чтобы исправить это, я сделал следующее: 1. Следуя решению @ k1th https://stackoverflow.com/a/33085955/889892 2. Запустите SecItemDelete в основном потоке (ранее он читался из основного потока, поэтому просто совместите это с удалением) ,

Извините, это снова возвращается :(

Senry
источник
0

Включите общий доступ к Связке ключей в возможностях вашего проекта, это должно решить проблему. введите описание изображения здесь

Ризван Ахмед
источник
0

Что сработало для меня

  • Включите общий доступ к связке ключей.
  • Используйте связку ключей как можно реже и кэшируйте данные в памяти, в пользовательских настройках, на диске и т. Д.
  • Если они не удались, повторите несколько раз операции CRUD связки ключей.
  • Используйте DispatchQueue.sync для хранения / удаления / обновления данных.
rockdaswift
источник
0

Для меня это была проблема с подписью приложения. Я просто переключился на правильную команду подписи в Xcode, и ошибка больше не возникала

Адам Смит
источник