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

ほとんどの場合、問題はありません。時々、キーチェーンへの書き込みまたはキーチェーンからの読み取りができず、重大なアサーションエラーを引き起こすアサーションエラーが発生することがあります。


同じ問題があり、再現できません... AppleのKeychainItemWrapperクラスを使用しています。同じエラーメッセージが表示され、Googleアナリティクスからクラッシュすることがあります。私はGoogle Analytics v3.02を使用しています。
Joey

また、AppStoreからのアプリでも大丈夫そうです。開発版アプリでのみ発生します。
Joey

2
私は、アプリストアのバージョンのためのcrashlyticsを持っており、残念ながらdevの上より頻度の少ないとはいえ、また、アプリケーションストアで発生するようです:/
トニー・

3
キーチェーンに格納されたデータがこのようにランダムに失われる可能性があるという事実は、アプリケーションにとってかなり致命的なエラーであるため、キーチェーンからの切り替えを考えています。
Tony

2
この断続的な問題も発生しています。-34018のケースを含め、secItemCopyMatchingから予期しないrcを取得すると、例外が発生します。キーチェーンから必要な値を取得したら、それをアプリのメモリにキャッシュし、キーチェーンにアクセスせずにそこから提供するメカニズムを(不本意ながら)追加しようとしました。しかし今、最初にそれを取得するための1つのキーチェーンアクセスが-34018で失敗するまれな状況が見られます。-34018の後で操作を再試行した人はいますか?
クリスマークル2014

回答:


45

iOS 10 / XCode 8の修正:

KeyChain資格を追加し、プロジェクト設定に移動します->機能->キーチェーン共有->キーチェーングループの追加+オン

ここで、アップルからの回答:

更新:iOS 8.3で-34018エラーを再現できるようになりました。これは、根本的な原因を特定して修正を行う最初のステップです。

いつものように、リリースタイムフレームにコミットすることはできませんが、これは多くの開発者に影響を与えており、本当にこれを解決したいと考えています。

以前、回避策としてキーチェーンにアクセスする前に、application:didFinishLaunchingWithOptionsおよびapplicationDidBecomeActive:に少し遅延を追加することをお勧めしました。しかし、それは実際には役に立たないようです。つまり、現時点ではアプリを再起動する以外に回避策はありません。

この問題はメモリのプレッシャーに関連しているように思われるため、メモリの警告をより積極的に処理することで問題が緩和される可能性があります

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

更新

はい、こちらが最新です。
これは、複数の原因が考えられる複雑な問題です。

  • 問題のいくつかのインスタンスは、不正なアプリ署名によって引き起こされます。この問題は100%再現可能であるため、このケースは簡単に区別できます。
  • この問題の一部の例は、iOSがアプリ開発をサポートする方法のバグが原因です(r。23,991,853)。これをデバッグすることは、OSの別のバグ(r。23,770,418)がその影響を覆い隠すという事実によって複雑になりました。つまり、この問題は、デバイスにメモリの負荷がかかっているときにのみ発生しました。これらの問題はiOS 9.3で解決されたと思われます。
  • この問題の原因はまだまだあると考えられます。

そのため、iOS 9.3以降を実行しているユーザーデバイス(Xcodeから通信されていないデバイス)でこの問題が発生した場合は、バグレポートを提出してください。バグレポートにデバイスのシステムログを含めてみてください(お客様のデバイスを扱う場合は注意が必要です。1つのオプションは、システムログを表示できるApple Configuratorをインストールするようにお客様に依頼することです)。バグを報告する場合は、念のため、バグ番号を投稿してください。

Appleを代表して、この恐ろしい問題の追跡を支援してくれた皆さんに感謝したいと思います。共有して楽しむ

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


2
この問題はiOS 9.2、iPhone 5Sでも再現されます。
DevGansta 2016

1
リンクしたスレッドでのAppleから最新の応答によると、iOS 9.3がこの問題を解決するようです。@daidai、この新しい情報で回答を更新していただけませんか?
jf 2016年

1
@YoonLeeもこれをiOS10で見ています-AWSの2.4.8 SDKも使用しています。AWSClientContext.m行54でエラーが発生しました。これを解決できる運はありますか?
CharlesA 2016

1
@YoonLeeところで、以下の回答のいずれかを使用してこれを解決しました:「ターゲット機能に対してKeyChain共有がオンになっています」
CharlesA

1
@CharlesAはい、私はその日に解決しました。あなたが正しいです。「KeyChain Entitlementがオンになっている」と思われるため、問題は修正されています。驚いたことに、このエラーは常に発生するわけではありません。とにかく、今私はこれをオンにしています。
ユン・リー

25

基本的には、以下をテストスクリプトの実行スクリプトとして追加して、.xcttestフォルダーにコード署名する必要があります。

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

デバイスでキーチェーンをテストすると、多くの-34018エラーが発生しましたが、これでなんとか修正できました。

テストターゲットに問題が存在しない場合、これはおそらく解決策ではありません。


これがテスト環境で修正されたことを確認しました。実際のテストターゲット(デバイスで実行されるビルドターゲットではなく、すべての単体テストを含むもの)に実行スクリプトを追加する必要がありました。また、これはデバイスの問題であり、シミュレータの問題ではないことも確認しました。
iwasrobbed

2
これを行うと、「:IDが見つかりませんコマンド/ bin / shが終了コード1で失敗しました」が表示されます $ CODE_SIGN_IDENTITYを持っていないと思います。どうすればこれを修正できますか?
ダニエルコフマン2014年

1
@DanielCoffman、ターゲット設定に移動し、コード署名IDで「iOS Developer」(またはその他の有効なID)を選択する必要があります。これでビルドエラーは修正されますが、少なくとも私にとってはキーチェーンの問題は修正されません。それでも-34018エラーコードが表示されます。
Marcin、2014年

3
マーチン、ありがとう。xcode 6ベータ版に切り替えたときに、このエラーが発生し始めました。このスレッドの提案は解決されていません。xcode 5に戻され、-34018は発生しなくなりました。
Daniel Coffman 14年

XCode 6.3を使用して以来、初めてこのエラーも発生します。
ウラジミール・Slavík

13

ソースコードを検査した後。キーチェーン機能は、独自のプロセス(アプリプロセスとは別)で実行されるセキュリティデーモンを介してアクセスされることに気付きました。

アプリとセキュリティ保護されたプロセスは、XPCと呼ばれるテクノロジーを介して「対話」します。

必要に応じて、XPCによる有名なlaunchdコマンドを介してsecuritydを起動します。デーモンがアクティビティモニターアプリで実行されていること(もちろんシミュレーターで実行されている場合)と、その親プロセスが起動されていることを確認できます。

私の推測では、なんらかの理由でセキュリティデーモンの起動に失敗したり、実行に時間がかかりすぎたりして、使用しようとしたときに準備ができていない可能性があります。

おそらく、デーモンを事前に起動する方法について考えることができます。

正確ではないことをお詫びします。あなたの調査をさらに進める一助となれば幸いです。


2
この問題が発生するのは、ディープリンクを介して次のアプリデリゲートメソッドでアプリを再び開いたときだけです。-(BOOL)application:(UIApplication *)application handleOpenURL:(NSURL *)url。アプリを起動するだけでキーチェーン作成は機能し、アプリを最小化および最大化しても機能します。この問題が発生するのは、ディープリンクで再び開いたときだけです。私は7のベータ4(機能]タブでキーホルダー共有)私のプロジェクトで構成されたMyApp.entitlementsのXcodeを持っていない
FranticRock

私のケースは、アプリがディープリンクされている場合にのみ発生するアレックスのケースに似ています。それ以外の場合は問題なく実行されます。別のアプリからアプリを開いたときに、一部のコンテキストが正しくない可能性があります。
CodeBrew、2015年

12

iOS 8 SDKを使用してXcode 6ベータ版でコードをビルドして実行した後も、同様の動作を観察しています(Xcode 5 / iOS 7では正常に動作しています)。Xcode 6では、iOSシミュレーターのSecItemCopyMatchingは常に-34018を返します。機能タブで「キーチェーンの共有」をオンにした後、それは働き始めました。

ただし、別の問題があります。(とりわけ)デモアプリケーションで使用される静的ライブラリを開発しています。上記のソリューションはデモアプリケーションプロジェクトで機能しますが、スタティックライブラリプロジェクトを単体テストしようとすると、まったく同じエラーが発生します。そして、問題は、静的ライブラリプロジェクトに(スタンドアロンアプリケーションではないため)[機能]タブがないことです。

ここにJorgeDeCorteが投稿したソリューションを試しましたが、テストターゲットにコード署名を付けましたが、うまくいきません。


8
そしてiOS 8ベータ3に戻る:)
Mustafa 14

7
そしてiOS 9.0に戻る
Alex Stone

4
そして今iOS 9.2に戻る:-(
Vamos

4
iOS 10ベータ2に戻る
Pranjal Bikash Das

3
iOS 10ベータ5に戻る
Pascal

6

アプリを起動するときにすべてのブレークポイントを無効にしてみてくださいXcodeからを。後で有効にすることができます。

(上記の回避策のどれも私にとってうまくいきませんでした)


奇妙な。私もこの問題を修正しているようです!シミュレータでデバッグを開始するたびに、-34018 OSStatusを経験する可能性があります。
midori 2016

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からアプリを実行し、開発プロセスを続行するのに役立ちました。
salabaha 2016

アドホックリリースをビルドするときに、使用されているPPを確認できます。XC:プロファイルが表示された場合は、それらを削除して、PPを更新してください。
dogsgod 2016年

これがどのように要因であるかがわかります。なんてめちゃくちゃなんだ!! 秋の片付けを行う
David

3

私はこの問題を修正しました(私はそう思います)。デバイスに有効な署名IDがないことを示すワイルドカードプロビジョニングプロファイルがありました。アプリのプロビジョニングプロファイルも有効でした。ワイルドカードプロファイルを削除すると、-34018エラーが発生しなくなりました。

また、ターゲットのビルド設定のコード署名セクションにリストされているコード署名IDとプロビジョニングプロファイルが、アプリのプロファイルと同じであることを確認しました(一般的な「iPhone開発者」のプロファイルではありません)。


これと同様に私のためにそれを修正しました。デバッグの場合はプロジェクトレベルのコード署名を「iPhone Developer」に、リリースの場合は「iPhone Distribution」に設定します。次に、メインターゲットのオーバーライドを削除して、同じように表示しました。以前は、キーチェーンへの保存が100%失敗していました。その後、キーチェーンでの保存は安定しているように見えます。
ジョウイ

2

アプリ(iOS 8.4)で-34018エラーが発生することは非常にまれでした。調査の結果、この問題はアプリがキーチェーンにデータをリクエストする頻度が高すぎる場合に発生することがわかりました。
たとえば、私の状況では、異なるアプリケーションモジュールからの1つの特定のキーに対する2つの読み取り要求が同時にありました。
それを修正するために、この値をメモリにキャッシュすることを追加しました


1

Xcode 6.2、iPhone 6、iOS 8.3を搭載したテストデバイスで実行していたところ、同じ問題が突然発生しました。明確に言うと、これはXcodeテストの実行中に発生したのではなく、デバイスで実際のアプリを実行中に発生しました。シミュレータでは問題なく、アプリ自体で実行すると、最近まで完全に問題がありませんでした。

私はここで見つけることができるすべての提案を試してみました。たとえば、デバイスのプロビジョニングプロファイルを削除し(すべて削除しました)、プロジェクトでキーチェーン共有機能を一時的に有効にします(実際には必要ありません)。 Xcodeの私の開発アカウントがすべての証明書やプロビジョニングプロファイルなどで完全に更新されていることを確認してください。

次に、一時的にアクセシビリティレベルをからkSecAttrAccessibleAfterFirstUnlockに変更kSecAttrAccessibleAlwaysThisDeviceOnlyしてアプリを実行しましたが、正常に動作し、キーチェーンに書き込むことができました。次に、それをに戻しましたがkSecAttrAccessibleAfterFirstUnlock、問題は「永久的に」解消したようです。


1

Xcode 8 Beta 3でこのバグに噛まれたばかりです。キーチェーン共有をオンにすることが唯一の解決策のようです。



1

(これはOPの質問に対する直接の回答ではありませんが、他の人を助けるかもしれません)

Xcodeをバージョン7.3.1から8.0に更新した後、シミュレーターで一貫してキーチェーンエラー-34018が発生し始めました。

daidaiの回答からのこのヒントに従って、

問題のいくつかのインスタンスは、不正なアプリ署名によって引き起こされます。この問題は100%再現可能であるため、このケースは簡単に区別できます。

ターゲットの署名セクションでプロビジョニングプロファイルがなんらかの方法で[なし]に設定されていることが発見されました。

ただし、この場合の問題を解決するには、プロビジョニングプロファイルフィールドを有効な値に設定するだけでは不十分でした。

さらなる調査の結果、プッシュ通知の資格にもエラーが表示されていることがわかりました。「プッシュ通知機能をアプリIDに追加する」と書かれています。ステップは完了しましたが、ステップ「プッシュ通知のエンタイトルメントをエンタイトルメントファイルに追加する」は実行されませんでした。

「Fix Issue」を押してプッシュ通知の問題を修正した後、キーチェーンエラーが解決されました。

この特定のターゲットでは、以前に「キーチェーン共有」資格がすでにオンになっています。これをオフにしても、これまでのところキーチェーンエラーが再発することはないため、この場合に必要かどうかは不明です。


0

iOS 9では、Address Sanitizerをオフにすると、デバイスで機能し始めました。


0

私にとってうまくいった唯一の解決策は、最初に指定されたキーのnilを格納し、次に別の操作で新しい値を格納することでした。既存の値を上書きしようとすると、エラー-34018により失敗します。しかし、最初にnilを保存しておけば、更新された値はすぐに正常に保存されます。


0

SecItemDelete APIを実行しているときに、この-34018の問題に今日遭遇しました。これを修正するために私がしたことは次のとおりです。1. @ k1thソリューションに従ってhttps://stackoverflow.com/a/33085955/889892 2.メインスレッドでSecItemDeleteを実行します(以前はメインスレッドから読み取られるため、これを削除に合わせます) 。

すみません、また戻ってきます:(



0

何がうまくいったか

  • キーチェーンの共有をオンにします。
  • キーチェーンの使用をできるだけ少なくし、データをメモリ、UserPreferences、ディスクなどにキャッシュします。
  • これらが失敗した場合、キーチェーンCRUD操作を何度も再試行します。
  • データの保存/削除/更新にはDispatchQueue.syncを使用します。

0

私にとっては、アプリ署名の問題でした。Xcodeで正しい署名チームに切り替えるだけで、エラーは発生しなくなりました

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.