web-dev-qa-db-fra.com

SecItemCopyMatching pour Touch ID sans repli du code

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?

31
jnic

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.

12
Keith Coughtrey

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:

  1. 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

  2. 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.


Conclusion

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;
                         }
];
11
bllakjakk

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.

10
ProgrammierTier

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.

1
whyoz

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");
1
bzz

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).

1
kishikawa katsumi