SecItemCopyMatching
を使用して、TouchIDで保護されているキーチェーンアイテムを取得しています。
ただし、Touch IDのロック解除に失敗した場合(またはユーザーが「パスコードの入力」を選択した場合)、独自のPIN入力UIを提示したいと思います。
どの時点でも、ユーザーにシステムパスコード入力UIが表示されないようにします。
LAContext
のevaluatePolicy
メソッドはこれを提供しますが、実際のキーチェーンセキュリティは提供せず、単にローカル認証を提供します。
したがって、これを実現するためにLAContext
を使用しません。これはSecItemCopyMatching
で可能ですか?
IOS 8.3以降では、パスコードフォールバックオプションは最初は非表示になっていますが、提示された最初の指が認識されない場合は引き続き表示されます。
IOS 9では、パスコードにフォールバックしない2つの新しいポリシーが追加されました。これらのポリシーは、kSecAccessControlTouchIDAnyおよびkSecAccessControlTouchIDCurrentSetです。
実稼働中のアプリの1つで作業しているときに、同様のジレンマが発生しました。 Touch IDのロック解除と、4桁のロック解除パスワードよりも強力なカスタムフォールバックメカニズム(ロック解除にはサーバーAPIが必要)が必要であることがわかりました。
それで、私たちがそれをどのように達成するかを説明しようと思います。同様のことが、Appstoreの購入と1PasswordアプリについてAppleによって行われると予想されます。
背景:
Touch IDを統合する2つのメカニズム:
Touch IDを使用して、キーチェーンに保存されている資格情報にアクセスします
問題:
デバイスにTouchIDもある場合、推奨される方法はTouch IDで認証することであり、パスコードはバックアップメカニズムです。
他のフォールバックメカニズムは許可されておらず、Appleはフォールバックユーザーインターフェイスのカスタマイズを許可していません
Touch IDを使用して、アプリで直接認証します(ローカル認証と呼ばれます)
問題:
セキュアエンクレーブにシークレットを保存したり、セキュアエンクレーブからシークレットを取得したりする権限は付与されていません
キーチェーンアクセスの場合とは異なり、Appleはバックアップとしてデバイスパスコード認証を許可しませんすべてのアプリケーションはカスタムUIで失敗したTouch IDの場合を処理するために独自のフォールバックを提供する必要があります
懸念:
キーチェーンへの機密情報の保存について:
このアプローチを使用したくなりましたが、Touch IDでの認証に失敗した場合の唯一のフォールバックはデバイスのパスコードであることに気づき、驚かされました。 iOSユーザーは通常4桁のパスコードを構成しますが、これはユーザーのカスタムパスワードよりも安全性が低くなります。
改築の例:
Appleは、ユーザーがTouch IDで認証に失敗した場合に、iTunesストア購入のフォールバックメカニズムとしてiCloudアカウントパスワード[カスタムフォールバックメカニズム]を使用します。
1Passwordアプリにも同様のアプローチがあります。
私たちのアプリでは、LocalAuthenticationを介してTouch IDで認証し、フォールバックメカニズムとして「アプリ固有のPINロック解除機能」またはクライアントのパスワードを使用します。
デバイスにパスワードを保存しません。デバイスにPINアプリ内で構成されます。
サンプルコード:
[self.laContext evaluatePolicy:LAPolicyDeviceOwnerAuthenticationWithBiometrics
localizedReason:reason
reply:^(BOOL success, NSError *error) {
if (success)
dispatch_async(dispatch_get_main_queue(), ^{ successBlock(); });
else
dispatch_async(dispatch_get_main_queue(), ^{ fallbackBlock(error); });
self.laContext = nil;
}
];
これはおそらくbllakjakkへのコメントであるはずですが、私の評判ではまだそうすることができません。
質問が具体的に尋ねていたので、私はこの答えを追加するだけです:
touchIDで保護されたキーチェーンアイテムを取得する
受け入れられた回答は、資格情報がデバイスに保存されていないシナリオに言及しています。
完全を期すために、アプリが外部エンティティに対して認証する必要があり、したがって資格情報をどこかに保存する必要がある場合は、ローカル認証よりもキーチェーンオプションを検討する必要があることをお伝えしたいと思います。
誰かがデバイスのパスコード(潜在的に弱い4桁など)を知っている場合にキーチェーンのフォールバックを介して認証できるという恐れは、ユーザーが自分の指紋を追加することを妨げるものは何もないため)重要なポイントですパスコードを持っている場合はデバイスに送信し、フォールバックを選択せずにキーチェーンまたはローカル認証を介して認証します。
したがって、フォールバックメカニズムの方が安全だと思われるためにキーチェーンを介したローカル認証を使用している場合は、その細部を見落としている可能性があり、そのため、安全なエンクレーブに資格情報を保存する機会を逃している可能性があります。
金融アプリケーションにTouchIDを実装しようとしており、Key-Chainを選択しています。その目的は、ユーザーがアプリでTouchIDを有効にしようとするときに、強力なデバイスパスコードの必要性についてユーザーを教育することです。
これが決定に役立つことを願っています。
次の設定により、「パスワードの入力」オプションを非表示/カスタマイズできます。
LAContext *context = [[LAContext alloc] init];
context.localizedFallbackTitle = @"";
オプションが消えるか、または:
LAContext *context = [[LAContext alloc] init];
context.localizedFallbackTitle = @"Disable TouchID";
オプションテキストをカスタマイズします。これはOPが求めていたものとは正確には一致しないことを私は知っていますが、それは最も確実に関連しており、欲求心に「フォールバック」する可能性があります。
次の手順で、Enter Password
ボタンを非表示にしてみてください。
1)グローバル関数を定義する
static bool new_isFallbackButtonVisible(id self, SEL _cmd)
{
return NO;
}
2)application:didFinishLaunchingWithOptions:
で、isFallbackButtonVisible
クラスのLAContext
メソッドを新しい実装に置き換えます。
class_replaceMethod(NSClassFromString(@"LAContext"), NSSelectorFromString(@"isFallbackButtonVisible"), (IMP)new_isFallbackButtonVisible, "v@:B");
キーチェーンTouchID統合でパスコードを使用してフォールバックメカニズムを無効にする方法はありません。代わりにLocalAuthenticationを使用してください(ただし、LocalAuthenticationは、キーチェーンとは関係ありませんが、TouchID認証UIを提供するだけです)。