web-dev-qa-db-ja.com

iOS KeyChainがバックグラウンドから値を取得しない

現在、ユーザー名(電子メール)と電子メールとパスワードのソルトハッシュをiOS KeyChainに保存しています。見つかったARC'ifiedバージョンを使用しています here

KeychainItemWrapper *wrapper = [[KeychainItemWrapper alloc] initWithIdentifier:@"MyCustomIdentifier" accessGroup:nil];
[wrapper setObject:APP_NAME forKey:(__bridge id)kSecAttrService];
[wrapper setObject:email forKey:(__bridge id)kSecAttrAccount];
[wrapper setObject:token forKey:(__bridge id)kSecValueData];

アプリがアクティブなときにネットワークコールのトークンを取り出す必要がある場合、これはすべて正常に機能します。クリーンスタートアップからのログインだけでなく、すべてのネットワークコールに対して機能します。アプリがバックグラウンドにあるときにトラブルが始まります。

これは散発的にしか発生しないことを念頭に置いてください。特定のiOSバージョンまたはデバイスに特定することはまだありません。

ユーザーが場所を旅行し(地域の監視)、サーバーのステータスを更新したい。他のすべてのネットワーク呼び出しと同じ方法で、キーチェーンからトークンを引き出し、ステータスを更新しようとします。しかし、一部のユーザーにとっては、値はゼロです。それなしでは、ネットワーク関連のものを更新できません。なぜこれがほとんどの場合に機能するが、わずかな割合では機能しないのですか?

KeychainItemWrapper *wrapper = [[KeychainItemWrapper alloc] initWithIdentifier:@"MyCustomIdentifier" accessGroup:nil];
NSString *token = [wrapper objectForKey:(__bridge id)kSecValueData];

Keychainwrapperの非ARCバージョンに戻りましたが、それでも同じ結果が得られます。これに関するフィードバックをお願いします。これはユーザーのごく一部にすぎませんが、修正したい問題であり、心配する必要はありません。前もって感謝します。

また、すべてのバックグラウンド作業がbackgroundTaskでセットアップされ、タイムアウトにならないようにします。キーチェーンを取り巻く作業に問題はありませんが、トークンが満たされるまで物事を進めません。

[〜#〜] edit [〜#〜]キーチェーンがバックグラウンドから値を取得しないという問題を見つけました。この質問を後で他の人にとって価値があると思うので、私は以下の答えを投稿して受け入れます。

79
Bill Burgess

私の質問は、その理由のためにマークに近かったが、完全ではなかった。ブログ、ブログ、チュートリアルを読んだ後、何が起こっているのかというヒントを与えてくれるものをようやく見つけました。

ロックされたホーム画面。キーチェーンのチュートリアルでは、常にキーチェーンのアクセシビリティ設定が空白のままであるため、Appleの最低/最も安全なアクセスレベルがデフォルトになります。ただし、ユーザーがロック画面にパスコードを持っている場合、このレベルではキーチェーンアクセスが許可されません。ビンゴ!これは、散発的な動作と、これが一部のユーザーにしか発生しない理由を説明しています。

1行のコードで、混乱全体を解決します。

[wrapper setObject:(__bridge id)kSecAttrAccessibleAlways forKey:(__bridge id)kSecAttrAccessible];

ユーザー名とパスワードの値を設定する場所にこの行を追加します。魔法のように機能します。これが誰かを助けることを願っています。作品をまとめることができるようになるまで、かなりの時間を混乱させました。

102
Bill Burgess

kSecAttrAccessibleAfterFirstUnlockの代わりにkSecAttrAccessibleAlwaysを使用します。


Appleのドキュメント から:

kSecAttrAccessibleAfterFirstUnlock
デバイスがユーザーによって一度ロック解除されるまで、再起動後にキーチェーン項目のデータにアクセスできません。

最初のロック解除後、データは次の再起動までアクセス可能のままです。 これは、バックグラウンドアプリケーションからアクセスする必要があるアイテムに推奨されます。暗号化されたバックアップを使用する場合、この属性を持つアイテムは新しいデバイスに移行します。

54
woof

私の場合、watchOS2はiOS側のキーチェーンデータにアクセスします。

最初は、kSecAttrAccessibleWhenUnlockedThisDeviceOnlyが使用されます。 iPhoneがロックされているかどうかに関係なく、データを読み取ることができます。時計がキーチェーンにアクセスしようとするとエラーが表示されるのは非常に混乱しています。:SecTrustEvaluate [リーフIssuerCommonName SubjectCommonName]

そして、いくつかのケースは次のようになります。:SecOSStatusWith error:[-25308] Error Domain = NSOSStatusErrorDomain Code = -25308 "ks_crypt:e00002e2 failed to 'oe' item(class 6、bag:0)keychainがロックされている間に試行されたアイテムへのアクセス。 」 UserInfo = {NSDescription = ks_crypt:e00002e2が 'oe'アイテムに失敗しました(クラス6、バッグ:0)キーチェーンがロックされているときにアイテムにアクセスしようとしました。}

さらに情報が得られたら、回答を更新します。

1
skingtree