SecItemAdd та SecItemCopyMatching повертає код помилки -34018 (errSecMissingEntitlement)


116

Іноді, коли я запускаю програму на пристрої з Xcode, я б намагався отримати доступ до брелка, але не вдався через помилку -34018. Це не відповідає жодному із задокументованих кодів помилок брелока та не може бути послідовно відтворене. (трапляється, можливо, 30% часу, і мені незрозуміло, чому це відбувається). Налагодження цієї проблеми дуже складно - це повна відсутність документації. Будь-яка ідея, що це викликає, і як це виправити? Я використовую Xcode 5 і запускаю iOS 7.0.4 на пристрої.

Про це є відкрите питання: https://github.com/soffes/sskeychain/isissue/52

EDIT: Додавання коду доступу брелока до запиту

Я використовую 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.
Джої

Крім того, здається, це все в порядку в додатку від AppStore. це відбувається лише у програмі для розробки версії.
Joey

2
У мене є крафлітики для версії магазину додатків, і, на жаль, це, здається, трапляється і в магазині додатків, хоча і рідше, ніж у розробника: /
Tony

3
Я думаю про відключення від брелка, оскільки той факт, що дані, що зберігаються в брелоку, може бути випадковим чином втрачений, як це, в основному, фатальна помилка для програми.
Тоні

2
Ми також спостерігаємо це переривчасте питання. Ми створюємо виняток, коли отримуємо несподіваний rc від secItemCopyMatching, включаючи випадок -34018. Ми спробували (неохоче) додати механізм, де, як тільки ми отримуємо необхідне нам значення з брелка, ми кешуємо його в пам’яті додатків, а потім подаємо його звідти без доступу до брелка. Але зараз ми спостерігаємо рідкісні випадки, коли той ключ-ланцюг доступу, щоб отримати його в першу чергу, не вдається з -34018. Хто-небудь намагався повторити операцію після -34018?
Кріс Маркл

Відповіді:


45

Виправлення iOS 10 / XCode 8:

Додати права KeyChain, Перейдіть до налаштувань проекту-> Можливості-> Спільний брелок-> Додати групи брелоків + Увімкнути

Відповідь тут, від Apple:

ОНОВЛЕННЯ: Нарешті ми змогли відтворити помилку -34018 на iOS 8.3. Це перший крок у виявленні першопричини, а потім виправлення.

Як завжди, ми не можемо взяти на себе зобов’язання щодо часового періоду випуску, але це вплинуло на багатьох розробників, і ми дуже хочемо вирішити це питання.

Раніше я пропонував додати невелику затримку в застосуванні: didFinishLaunchingWithOptions та applicationDidBecomeActive: перед тим як отримати доступ до брелоку як обхідного рішення. Однак це насправді не допомагає. Це означає, що наразі не існує жодного відомого рішення, крім повторного запуску програми.

Здається, ця проблема пов'язана з тиском пам'яті, тому, можливо, більш агресивна робота з попередженнями про пам'ять може полегшити проблему

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

ОНОВЛЕННЯ

Гаразд, ось останні.
Це складна проблема з кількома можливими причинами:

  • Деякі випадки проблеми спричинені неправильним підписанням програми. Ви можете легко відрізнити цей випадок, оскільки проблема є 100% відтворюваною.
  • Деякі випадки проблеми викликані помилкою в тому, як iOS підтримує розробку додатків (r. 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


2
Випуск все ще відтворюється на iOS 9.2, iPhone 5S.
DevGansta

1
Схоже, iOS 9.3 повинен вирішити цю проблему відповідно до останньої відповіді Apple у потоці, яку ви пов’язали. @daidai, чи можете ви оновити свою відповідь цією новою інформацією?
jf

1
@YoonLee також бачу це з iOS10 - також використовуючи 2.4.8 SDK AWS. Помилка, ініційована в рядку 54 AWSClientContext.m. Маєш удачу вирішити це?
CharlesA

1
@YoonLee btw, щойно вирішив це, використовуючи одну з відповідей нижче: "Обмін KeyChain увімкнено для цільових можливостей"
CharlesA

1
@CharlesA Так, я цього дня вирішив. Ти правий. Здається, "KeyChain Права включення" виправляє проблему. Дивно, але ця помилка спрацьовує не завжди. У всякому разі, зараз я це вмикаю.
Йон Лі

25

По суті, ви повинні кодирувати свою папку .xcttest, додавши наступне як сценарій запуску у вашу тестову ціль.

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

Я отримав багато -34018 помилок під час тестування своєї брелка на пристрої, і це вдалося виправити.

Якщо проблеми не існує у вашій тестовій цілі, можливо, це не є рішенням.


Підтверджено це виправлено у тестовому середовищі. Мені довелося додати сценарій запуску до фактичної тестової цілі (наприклад, ті, які / всі одиничні тести, а не ціль збірки, яка працює на пристрої). Також підтверджено, що це лише проблема на пристрої, а не на тренажері.
iwasrobbed

2
Я отримую ": не знайдено ідентичність Command / bin / sh не вдалося з кодом виходу 1", коли я це роблю? Гадаю, що у мене немає $ CODE_SIGN_IDENTITY. Будь-яка ідея, як я це виправляю?
Даніель Коффман

1
@DanielCoffman, ви повинні перейти до своїх цільових налаштувань і в полі підпису коду вибрати "iOS Developer" (або будь-яку іншу дійсну особу). Це виправляє помилку збирання, однак принаймні для мене це не вирішує проблему Keychain. Я все одно отримую -34018 код помилки.
Марцін

3
Дякую Марчін. Я почав отримувати цю помилку, коли перейшов на бета-версію xcode 6. Жодна пропозиція в цій темі не вирішена. Повернення до xcode 5 та -34018 більше не відбувається.
Даніель Коффман

Я також відчуваю цю помилку вперше після використання XCode 6.3.
Владимир Славік

13

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

Ваш додаток та захищений процес спільно спілкуються через технологію під назвою XPC .

Якщо необхідно, захищений запускається за допомогою відомої XPC команди. Ви, ймовірно, можете перевірити, що демон працює в додатку Monitor Monitor (якщо звичайно він працює в Simulator) і чи запускається його батьківський процес.

Я думаю, тут можливо, що з незрозумілої причини демон захисту не вдається запуститись чи зробити це занадто повільно і не готовий при спробі його використовувати.

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

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


2
Цю проблему я отримую лише тоді, коли мій додаток повторно відкривається через посилання Deep із наступним методом делегування додатка: - (BOOL) додаток: (UIApplication *) ручка програмиOpenURL: (NSURL *) URL. Якщо я лише запускаю програму, написання брелока працює, і якщо я мінімізую і максимізую додаток, він все ще працює. Тільки коли я повторно відкриваюсь за допомогою глибокого зв’язку, виникає ця проблема. У мене в моєму проекті налаштований MyApp.entitlements (Обмін брелками на вкладці "Можливості") Xcode 7 beta 4.
FranticRock

Мій випадок схожий на Алекс, що трапляється лише тоді, коли додаток є глибоко пов'язаним. Інакше це працює нормально. Можливо, якийсь контекст не підходить, коли додаток відкрито з іншого додатка.
CodeBrew

12

Я спостерігаю подібну поведінку після складання та запуску свого коду в Xcode 6 beta з iOS 8 SDK (він працює правильно з Xcode 5 / iOS 7). У Xcode 6 в iOS Simulator SecItemCopyMatching завжди повертається -34018. Він почав працювати після включення "Спільного використання брелоків" на вкладці "Можливості".

Однак у мене є інше питання. Я розробляю статичну бібліотеку, яку використовує (серед інших) демонстраційний додаток. Вищевказане рішення працює для демо-програми, але коли я намагаюся перевірити проект статичної бібліотеки, у мене точно така ж помилка. І проблема полягає в тому, що мій проект статичної бібліотеки не має вкладки "Можливості" (оскільки це не окремий додаток).

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


8
І ще в iOS 8 beta 3 :)
Мустафа

7
І ще в iOS 9.0
Alex Stone,

4
А тепер ще в iOS 9.2 :-(
Vamos

4
Повернутися в iOS 10 beta 2
Pranjal Bikash Das

3
І ще в iOS 10 beta 5
Pascal

6

Спробуйте вимкнути всі точки перерви під час запуску програми з Xcode. Ви можете ввімкнути їх згодом.

(Жоден із перерахованих вище способів не працював для мене)


Дивно. Здається, вирішити цю проблему і для мене! Кожен раз, коли я починав налагоджувати симулятор, я міг відчути -34018 OSStatus.
midori

4

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


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

4

Мене це теж покусало, і жоден з інших обхідних шляхів не мав успіху. Потім я очистив свої профілі резервування на самих пристроях, видаливши їх, пов’язані з моїм додатком, а також усі профілі підстановки (це, мабуть, суть). Для цього перейдіть до вікна «Пристрої» у Xcode та клацніть правою кнопкою миші ваш (підключений) телефон:

Клацніть на "Показати профілі резервування" та видаліть пов'язані з ними, а особливо профілі команди:

у тому числі зірочкою. Після перевстановлення програми все повернулося до норми.


Це допомогло мені запустити додаток з Xcode та продовжити процес розробки.
салабаха

Створюючи версію AdHoc, ви можете перевірити, які ПП використовуються. якщо ви бачите будь-які XC: профілі, видаліть їх та оновіть PP!
doggod

Я бачу, як це може бути фактором. Який безлад там !! Деяка осінь прибирає
Девід

3

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

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


Подібно до цього виправлено це для мене. Встановіть підпис коду на рівні проекту на "Розробник iPhone" для налагодження та "Розподіл iPhone" для випуску. Потім я зняв переоцінки головної цілі, щоб вони показали те саме. Раніше економити в брелоку було невдало 100% часу. Згодом збереження в брелоку здається стабільним.
jowie

2

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


1

У мене з тією самою проблемою, на самому силі, працював на тестовому пристрої з Xcode 6.2, iPhone 6, iOS 8.3. Щоб було зрозуміло, цього не відчували під час запуску тестів Xcode, а скоріше під час роботи фактичного додатка на моєму пристрої. У тренажері це було чудово, а в самому додатку він працював зовсім недавно.

Я спробував усі пропозиції, які я міг знайти тут, як-от видалити профілі забезпечення на моєму пристрої (я видалив ВСІ з них), тимчасово увімкнувши можливість спільного використання брелоків у моєму проекті (навіть якщо це насправді не потрібно), роблячи впевнений, що мій обліковий запис у Xcode був повністю оновлений усіма сертифікатами та профілями забезпечення тощо. Нічого не допомогло.

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


1

Щойно покусав цю помилку на Xcode 8 Beta 3. Увімкнення спільного використання брелоків здається єдиним рішенням.


1

У мене було те саме питання. Виправлено це за допомогою налаштування спільного використання брелоків.


1

(це не пряма відповідь на питання ОП, але може допомогти іншим)

Початок отримувати помилку брелока -34018 послідовно в тренажері після оновлення Xcode з версії 7.3.1 до 8.0.

Слідуючи цій підказці з відповіді Дайдая ,

Деякі випадки проблеми спричинені неправильним підписанням програми. Ви можете легко відрізнити цей випадок, оскільки проблема є 100% відтворюваною.

було виявлено, що в розділах підписання цілі в Профілі забезпечення якось встановлено значення None.

Однак встановлення полів профілю надання на дійсні значення було недостатньо для вирішення проблеми в цьому випадку.

Подальше розслідування показало, що права Push Notifications також виявили помилку. У ньому написано "Додати функцію Push Notifications до ідентифікатора додатка". крок був завершений, але кроку "Додавання прав Push Notifications у файл ваших прав" не було.

Після натискання «Виправити випуск», щоб виправити проблему Push Notification, помилка брелка була усунена.

Для цієї конкретної цілі, права на "обмін брелками" вже були включені в попередній час. Вимкнення його не призвело до того, що помилка брелоку знову з’являється, тому не ясно, чи потрібно це в цьому випадку.


0

У iOS 9 я вимкнув Address Sanitizer і він почав працювати на пристрої.


0

Єдине рішення, яке працювало для мене, було спочатку зберігати нуль для вказаного ключа, а потім зберігати моє нове значення окремою операцією. Він не вдасться через помилку -34018, якби я спробував перезаписати існуюче значення. Але поки я зберігав нуль спочатку, то оновлене значення буде успішно зберігатися відразу після цього.


0

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

Вибачте, що повертається знову :(


0

Увімкніть обмін брелоком у можливостях вашого проекту, це повинно вирішити проблему. введіть тут опис зображення


0

Що працювало на мене

  • Увімкніть обмін брелоками.
  • Використовуйте брелок як можна менше і кешуйте дані в пам'яті, UserPreferences, диску тощо.
  • Багато разів повторіть операції з управлінням ключами, якщо вони не вдалися.
  • Використовуйте DispatchQueue.sync для зберігання / видалення / оновлення даних.

0

Для мене це була проблема підписання програми. Я просто перейшов на правильну команду підписання в Xcode і помилка більше не сталася

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.