J'utilise SecItemCopyMatching
pour récupérer un élément de trousseau protégé par Touch ID.
Cependant, si le déverrouillage Touch ID échoue (ou si l'utilisateur sélectionne "Entrer le code d'accès"), je souhaite présenter ma propre interface utilisateur de saisie du code PIN.
Je ne veux pas que l'utilisateur se voit présenter l'interface utilisateur de saisie du code d'accès du système à tout moment.
La méthode LAContext
's evaluatePolicy
fournit ceci, mais n'offre aucune sécurité de trousseau réelle, mais simplement une authentification locale.
Je n’utiliserai donc pas LAContext
pour y parvenir. Est-ce possible avec SecItemCopyMatching
?
Sur iOS 8.3 et les versions ultérieures, l'option de remplacement du code est initialement masquée, mais elle apparaît quand même si le premier doigt présenté n'est pas reconnu.
Pour iOS 9, deux nouvelles stratégies ont été ajoutées pour ne pas utiliser le code secret. Ces règles sont kSecAccessControlTouchIDAny et kSecAccessControlTouchIDCurrentSet.
Nous avons eu le même dilemme lorsque nous travaillions sur l'une de nos applications en production. Nous nous sommes rendu compte que nous avions besoin d'un déverrouillage par ID tactile ainsi que d'un mécanisme de secours personnalisé (nécessitant une API de serveur pour le déverrouillage), qui est plus puissant que le mot de passe à 4 chiffres.
Alors, permettez-moi d’essayer d’expliquer comment nous y parvenons. Apple devrait procéder de la même façon pour l’Appstore et l’application 1Password.
Contexte:
Deux mécanismes pour intégrer Touch ID:
Utiliser Touch ID pour accéder aux informations d'identification stockées dans le trousseau
Problème:
Si un périphérique possède également un Touch ID, la méthode recommandée consiste à s'authentifier avec Touch ID et le code de passe est le mécanisme de sauvegarde.
Aucun autre mécanisme de secours n'est autorisé et Apple n'autorise pas la personnalisation de l'interface utilisateur de secours
Utilisez Touch ID pour vous authentifier directement avec l'application (appelée authentification locale).
Problème:
Aucune autorisation n'est accordée pour stocker ou récupérer des secrets dans Secure Enclave.
Contrairement au cas d'accès au trousseau, Apple n'autorise pas l'authentification par mot de passe de périphérique en tant que sauvegarde Chaque application doit fournir sa propre solution de secours pour traiter les cas d'échec Touch ID avec une interface utilisateur personnalisée
Préoccupation:
À propos du stockage d'informations sensibles dans le trousseau:
Nous étions tentés d'utiliser cette approche, mais nous avons été pris de court en réalisant que la seule solution de rechange en cas d'échec de l'authentification avec Touch ID est le code d'authentification de l'appareil. Les utilisateurs iOS configurent généralement un code d'authentification à quatre chiffres, ce qui est moins sécurisé que les mots de passe personnalisés des utilisateurs.
Exemples de lifting:
Apple utilise le mot de passe de votre compte iCloud [mécanisme de secours personnalisé] comme mécanisme de secours pour l'achat d'iTunes Store si l'utilisateur ne parvient pas à s'authentifier avec Touch ID.
L'application 1Password a également une approche similaire.
Dans notre application, nous nous authentifions avec Touch ID via LocalAuthentication. Nous utilisons notre fonctionnalité spécifique de déverrouillage PIN ou le mot de passe du client comme mécanisme de secours.
Nous ne stockons pas le mot de passe sur le périphérique. L'échec de l'authentification avec Touch ID nécessite une authentification complète via l'API du serveur, si le périphérique n'a pas de PIN configuré dans l'application.
Exemple de code:
[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;
}
];
Cela devrait probablement être un commentaire pour bllakjakk, mais ma réputation ne me permet pas encore de le faire.
Je ne fais qu'ajouter cette réponse car la question portait spécifiquement sur:
chercher un élément de trousseau protégé par Touch ID
La réponse acceptée mentionne un scénario dans lequel aucune information d'identification n'est stockée sur le périphérique.
Par souci d'exhaustivité, je voulais mentionner que si votre application doit s'authentifier auprès d'une entité externe et que vous devez par conséquent stocker les informations d'identification quelque part, l'option Chaîne de clés est celle à prendre en compte par rapport à l'authentification locale.
La crainte que quelqu'un puisse s'authentifier via le repli pour Key-Chain s'ils connaissent le code de passe du périphérique (potentiellement faible, à quatre chiffres, etc.) est un point discutable, car rien n'empêche un utilisateur d'ajouter sa propre empreinte digitale au périphérique s'ils possèdent le code d'authentification, puis authentification via Key-Chain ou Authentification locale sans avoir à sélectionner le repli .
Par conséquent, si vous utilisez l'authentification locale sur une chaîne principale parce que vous estimez que le mécanisme de secours est plus sûr, vous risquez de négliger ce détail mineur et de laisser passer l'opportunité de stocker les informations d'identification dans l'enclave sécurisée.
Nous sommes sur le point d'implémenter TouchID pour une application financière et optons pour Key-Chain. L'intention est d'éduquer nos utilisateurs sur le besoin de codes de passe forts pour les appareils au moment où ils essaient d'activer TouchID pour notre application.
J'espère que cela vous aide à prendre une décision.
Vous pouvez masquer/personnaliser l'option "Entrer le mot de passe" en définissant:
LAContext *context = [[LAContext alloc] init];
context.localizedFallbackTitle = @"";
et l'option disparaîtra, ou:
LAContext *context = [[LAContext alloc] init];
context.localizedFallbackTitle = @"Disable TouchID";
pour personnaliser le texte de l’option. Bien que je sache que ce n'est pas exactement ce que le PO demandait, il est très certainement lié et pourrait "se replier" dans des esprits désireux.
Vous pouvez essayer de masquer le bouton Enter Password
en procédant comme suit:
1) définir la fonction globale
static bool new_isFallbackButtonVisible(id self, SEL _cmd)
{
return NO;
}
2) dans votre application:didFinishLaunchingWithOptions:
, remplacez la méthode isFallbackButtonVisible
de la classe LAContext
par votre nouvelle implémentation en appelant
class_replaceMethod(NSClassFromString(@"LAContext"), NSSelectorFromString(@"isFallbackButtonVisible"), (IMP)new_isFallbackButtonVisible, "v@:B");
Il n'y a aucun moyen de désactiver le mécanisme de secours en utilisant un code d'accès dans l'intégration Keychain TouchID. Utilisez plutôt LocalAuthentication (mais LocalAuthentication fournit simplement une interface utilisateur TouchID avec auth, bien qu’elle ne soit pas liée au trousseau).