Share via


Cartes à puce

Cette rubrique explique comment les applications de 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 carte à puce physiques, créer des cartes à puce virtuelles, communiquer avec des cartes à puce, authentifier des utilisateurs, réinitialiser des PIN d’utilisateur et supprimer ou déconnecter des cartes à puce.

Configurer le manifeste de l’application

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

Accéder à des lecteurs de cartes et à des cartes à puce connectés

Vous pouvez interroger les lecteurs et les cartes à puce jointes en transmettant l’ID de l’appareil (spécifié dans DeviceInformation) à la méthode SmartCardReader.FromIdAsync . Pour accéder aux cartes à puce actuellement attachées au 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 configurer votre application de manière à surveiller les événements CardAdded en implémentant une méthode pour déterminer le comportement de l’application lors de l’insertion d’une carte.

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

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

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 un SmartCardPinPolicy. Le nom convivial est généralement fourni à l’application, mais votre application doit fournir une clé d’administration et générer une instance du SmartCardPinPolicy actuel 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. Passez 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 que RequestVirtualSmartCardCreationAsync a retourné l’objet SmartCardProvisioning associé, le carte intelligent virtuel est provisionné et prêt à être utilisé.

Notes

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

Gérer les demandes d’authentification

Pour authentifier des utilisateurs au moyen de cartes à puce ou de cartes à puce virtuelles, votre application doit être en mesure de répondre aux demandes entre les données des clés d’administration stockées sur la carte et les données des clés d’administration gérées par le serveur d’authentification ou l’outil de gestion.

L’exemple de code suivant montre comment prendre en charge l’authentification par carte à puce pour des services ou la modification des détails d’une carte à puce physique ou virtuelle. Si les données générées à l’aide de la clé d’administration sur la carte (« challenge ») sont identiques aux données de la 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;
    }
}

Ce code est référencé dans le reste de cette rubrique pour illustrer comment remplir une action d’authentification et comment appliquer des modifications aux informations d’une carte à puce et d’une carte à puce virtuelle.

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

Maintenant que nous avons défini la logique pour les demandes d’authentification, nous pouvons soit communiquer avec le lecteur pour accéder à la carte à puce, soit accéder à une carte à puce virtuelle à des fins d’authentification.

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

  2. Passez ensuite la valeur de demande de la carte et la clé d’administration fournie par le service ou l’outil de gestion à ChallengeResponseAlgorithm (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 PIN d’utilisateur

Pour modifier le code PIN 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 afin d’effectuer cette opération.
  3. Si le code PIN a été correctement modifié, l’appel retourne true.
SmartCardProvisioning provisioning =
    await SmartCardProvisioning.FromSmartCardAsync(card);

bool result = await provisioning.RequestPinChangeAsync();

Pour demander une réinitialisation du code PIN :

  1. Appelez RequestPinResetAsync pour initier l’opération. Cet appel inclut une méthode SmartCardPinResetHandler qui représente la carte intelligente et la demande de réinitialisation de broche.

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

  3. Si la demande réussit, l’appel à RequestPinResetAsync est terminé, et la valeur true est retournée si le code PIN est correctement 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’un carte intelligent physique est supprimé, un événement CardRemoved se déclenche lorsque le carte est supprimé.

Associez le déclenchement de cet événement sur le lecteur de carte à la méthode qui définit le comportement de votre application suite au retrait de la carte ou du lecteur comme gestionnaire d’événements. Vous pouvez simplement fournir à l’utilisateur une notification indiquant que la carte a été retirée.

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

La suppression d’un carte intelligent virtuel est gérée par programmation en récupérant d’abord le carte, puis en appelant RequestVirtualSmartCardDeletionAsync à partir de l’objet retourné SmartCardProvisioning.

bool result = await SmartCardProvisioning
    .RequestVirtualSmartCardDeletionAsync(card);