Partager via


Cartes à puce

Cette rubrique explique comment les applications plateforme Windows universelle (UWP) peuvent utiliser des cartes à puce pour connecter des utilisateurs à des services réseau sécurisés, notamment comment accéder aux lecteurs de cartes à puce physiques, créer des cartes à puce virtuelles, communiquer avec des cartes à puce, authentifier les utilisateurs, réinitialiser les codes CONFIDENTIELs des utilisateurs et supprimer ou déconnecter des cartes à puce.

Configurer le manifeste de l’application

Pour que votre application puisse authentifier les utilisateurs à l’aide de cartes à puce ou de cartes à puce virtuelles, vous devez définir la fonctionnalité Certificats utilisateur partagés dans le fichier Package.appxmanifest du projet.

Accéder aux lecteurs de cartes connectées et aux cartes à puce

Vous pouvez rechercher des lecteurs et des cartes à puce jointes en passant l’ID d’appareil (spécifié dans DeviceInformation) à la méthode SmartCardReader.FromIdAsync. Pour accéder aux cartes à puce actuellement attachées à l’appareil lecteur retourné, appelez SmartCardReader.FindAllCardsAsync.

string selector = SmartCardReader.GetDeviceSelector();
DeviceInformationCollection devices =
    await DeviceInformation.FindAllAsync(selector);

foreach (DeviceInformation device in devices)
{
    SmartCardReader reader =
        await SmartCardReader.FromIdAsync(device.Id);

    // For each reader, we want to find all the cards associated
    // with it.  Then we will create a SmartCardListItem for
    // each (reader, card) pair.
    IReadOnlyList<SmartCard> cards =
        await reader.FindAllCardsAsync();
}

Vous devez également permettre à votre application d’observer les événements CardAdded en implémentant une méthode pour gérer le comportement de l’application lors de l’insertion de carte.

private void reader_CardAdded(SmartCardReader sender, CardAddedEventArgs args)
{
  // A card has been inserted into the sender SmartCardReader.
}

Vous pouvez ensuite transmettre chaque objet SmartCard retourné à SmartCardProvisioning pour accéder aux méthodes qui permettent à votre application d’accéder à votre application et de personnaliser sa configuration.

Créer une carte à puce virtuelle

Pour créer une carte à puce virtuelle à l’aide de SmartCardProvisioning, votre application doit d’abord fournir un nom convivial, une clé d’administration et une SmartCardPinPolicy. Le nom convivial est généralement fourni à l’application, mais votre application doit toujours fournir une clé d’administration et générer une instance de la smartCardPinPolicy actuelle avant de passer les trois valeurs à RequestVirtualSmartCardCreationAsync.

  1. Créer une instance d’un SmartCardPinPolicy
  2. Générez la valeur de la clé d’administration en appelant CryptographicBuffer.GenerateRandom sur la valeur de clé d’administration fournie par le service ou l’outil de gestion.
  3. Transmettez ces valeurs avec la chaîne FriendlyNameText à RequestVirtualSmartCardCreationAsync.
SmartCardPinPolicy pinPolicy = new SmartCardPinPolicy();
pinPolicy.MinLength = 6;

IBuffer adminkey = CryptographicBuffer.GenerateRandom(24);

SmartCardProvisioning provisioning = await
     SmartCardProvisioning.RequestVirtualSmartCardCreationAsync(
          "Card friendly name",
          adminkey,
          pinPolicy);

Une fois RequestVirtualSmartCardCreationAsync retourné l’objet SmartCardProvisioning associé, la carte à puce virtuelle est provisionnée et prête à être utilisée.

Remarque

Pour créer une carte à puce virtuelle à l’aide d’une application UWP, l’utilisateur exécutant l’application doit être membre du groupe administrateurs. Si l’utilisateur n’est pas membre du groupe Administrateurs, la création de carte à puce virtuelle échoue.

Gérer les défis liés à l’authentification

Pour vous authentifier avec des cartes à puce ou des cartes à puce virtuelles, votre application doit fournir le comportement permettant d’effectuer des défis entre les données de clé d’administration stockées sur la carte et les données de clé d’administration conservées par le serveur d’authentification ou l’outil de gestion.

Le code suivant montre comment prendre en charge l’authentification par carte à puce pour les services ou la modification des détails de carte physique ou virtuelle. Si les données générées à l’aide de la clé d’administration sur la carte (« défi ») sont identiques aux données de clé d’administration fournies par le serveur ou l’outil de gestion (« adminkey »), l’authentification réussit.

static class ChallengeResponseAlgorithm
{
    public static IBuffer CalculateResponse(IBuffer challenge, IBuffer adminkey)
    {
        if (challenge == null)
            throw new ArgumentNullException("challenge");
        if (adminkey == null)
            throw new ArgumentNullException("adminkey");

        SymmetricKeyAlgorithmProvider objAlg = SymmetricKeyAlgorithmProvider.OpenAlgorithm(SymmetricAlgorithmNames.TripleDesCbc);
        var symmetricKey = objAlg.CreateSymmetricKey(adminkey);
        var buffEncrypted = CryptographicEngine.Encrypt(symmetricKey, challenge, null);
        return buffEncrypted;
    }
}

Vous verrez ce code référencé tout au long du reste de cette rubrique, nous avons examiné comment effectuer une action d’authentification et comment appliquer des modifications aux informations de carte à puce et de carte à puce virtuelle.

Vérifier la réponse d’authentification de carte à puce ou de carte à puce virtuelle

Maintenant que nous avons la logique pour les défis d’authentification définis, nous pouvons communiquer avec le lecteur pour accéder à la carte à puce, ou autrement, accéder à une carte à puce virtuelle pour l’authentification.

  1. Pour commencer le défi, appelez GetChallengeContextAsync à partir de l’objet SmartCardProvisioning associé à la carte à puce. Cela génère une instance de SmartCardChallengeContext qui contient la valeur Challenge de la carte.

  2. Ensuite, passez la valeur de défi de la carte et la clé d’administration fournie par le service ou l’outil de gestion au ChallengeResponseAlgorithm que nous avons défini dans l’exemple précédent.

  3. VerifyResponseAsync retourne true si l’authentification réussit.

bool verifyResult = false;
SmartCard card = await rootPage.GetSmartCard();
SmartCardProvisioning provisioning =
    await SmartCardProvisioning.FromSmartCardAsync(card);

using (SmartCardChallengeContext context =
       await provisioning.GetChallengeContextAsync())
{
    IBuffer response = ChallengeResponseAlgorithm.CalculateResponse(
        context.Challenge,
        rootPage.AdminKey);

    verifyResult = await context.VerifyResponseAsync(response);
}

Modifier ou réinitialiser un code confidentiel utilisateur

Pour modifier le code confidentiel associé à une carte à puce :

  1. Accédez à la carte et générez l’objet SmartCardProvisioning associé.
  2. Appelez RequestPinChangeAsync pour afficher une interface utilisateur à l’utilisateur pour terminer cette opération.
  3. Si le code confidentiel a été correctement modifié, l’appel retourne true.
SmartCardProvisioning provisioning =
    await SmartCardProvisioning.FromSmartCardAsync(card);

bool result = await provisioning.RequestPinChangeAsync();

Pour demander une réinitialisation de code confidentiel :

  1. Appelez RequestPinResetAsync pour lancer l’opération. Cet appel inclut une méthode SmartCardPinResetHandler qui représente la carte à puce et la demande de réinitialisation d’épingle.

  2. SmartCardPinResetHandler fournit des informations que notre ChallengeResponseAlgorithm, encapsulé dans un appel SmartCardPinResetDeferral, utilise pour comparer la valeur de défi de la carte et la clé d’administration fournie par le service ou l’outil de gestion pour authentifier la demande.

  3. Si le défi réussit, l’appel RequestPinResetAsync est terminé ; retourne true si le code confidentiel a été réinitialisé.

SmartCardProvisioning provisioning =
    await SmartCardProvisioning.FromSmartCardAsync(card);

bool result = await provisioning.RequestPinResetAsync(
    (pinResetSender, request) =>
    {
        SmartCardPinResetDeferral deferral =
            request.GetDeferral();

        try
        {
            IBuffer response =
                ChallengeResponseAlgorithm.CalculateResponse(
                    request.Challenge,
                    rootPage.AdminKey);
            request.SetResponse(response);
        }
        finally
        {
            deferral.Complete();
        }
    });
}

Supprimer une carte à puce ou une carte à puce virtuelle

Lorsqu’une carte à puce physique est supprimée, un événement CardRemoved se déclenche lorsque la carte est supprimée.

Associez le déclenchement de cet événement au lecteur de carte à la méthode qui définit le comportement de votre application sur la suppression de carte ou de lecteur en tant que gestionnaire d’événements. Ce comportement peut être quelque chose aussi simplement que de fournir une notification à l’utilisateur que la carte a été supprimée.

reader = card.Reader;
reader.CardRemoved += HandleCardRemoved;

La suppression d’une carte à puce virtuelle est gérée par programme en récupérant d’abord la carte, puis en appelant RequestVirtualSmartCardDeletionAsync à partir de l’objet retourné SmartCardProvisioning.

bool result = await SmartCardProvisioning
    .RequestVirtualSmartCardDeletionAsync(card);