Cartões inteligentesSmart cards

Este tópico explica como os aplicativos da Plataforma Universal do Windows (UWP) podem usar cartões inteligentes para conectar os usuários à serviços de rede seguros, incluindo como acessar os leitores de cartão inteligente físicos, criar cartões inteligentes virtuais, se comunicar com cartões inteligentes, autenticar usuários, redefinir PINs de usuário e como remover ou desconectar cartões inteligentes.This topic explains how Universal Windows Platform (UWP) apps can use smart cards to connect users to secure network services, including how to access physical smart card readers, create virtual smart cards, communicate with smart cards, authenticate users, reset user PINs, and remove or disconnect smart cards.

Configurar o manifesto do aplicativoConfigure the app manifest

Para que o seu aplicativo possa autenticar usuários usando cartões inteligentes ou cartões inteligentes virtuais, você deve configurar o recurso Certificados de Usuário Compartilhado no arquivo do projeto Package.appxmanifest.Before your app can authenticate users using smart cards or virtual smart cards, you must set the Shared User Certificates capability in the project Package.appxmanifest file.

Acesse leitores de cartões conectados e cartões inteligentesAccess connected card readers and smart cards

Você pode consultar leitores e cartões inteligentes conectados passando a ID de dispositivo (especificada em DeviceInformation) para o método SmartCardReader.FromIdAsync.You can query for readers and attached smart cards by passing the device ID (specified in DeviceInformation) to the SmartCardReader.FromIdAsync method. Para acessar os cartões inteligentes atualmente conectados a um dispositivo leitor retornado, chame SmartCardReader.FindAllCardsAsync.To access the smart cards currently attached to the returned reader device, call 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();
}

Você deve também habilitar seu aplicativo para observar eventos CardAdded e implementar uma função para determinar o comportamento do aplicativo na inserção do cartão.You should also enable your app to observe for CardAdded events by implementing a method to handle app behavior on card insertion.

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

Em seguida, você pode passar cada objeto SmartCard retornado para SmartCardProvisioning acessar os métodos que permitem ao seu aplicativo acessar e personalizar sua configuração.You can then pass each returned SmartCard object to SmartCardProvisioning to access the methods that allow your app to access and customize its configuration.

Crie um cartão inteligente virtualCreate a virtual smart card

Para criar um cartão inteligente virtual usando SmartCardProvisioning, seu aplicativo precisará primeiro fornecer um nome amigável, uma chave de administração e um SmartCardPinPolicy.To create a virtual smart card using SmartCardProvisioning, your app will first need to provide a friendly name, an admin key, and a SmartCardPinPolicy. O nome amigável é geralmente algo fornecido para o aplicativo, mas o seu aplicativo ainda precisará fornecer uma chave de administração e gerar uma instância do SmartCardPinPolicy atual antes de passar os três valores para RequestVirtualSmartCardCreationAsync.The friendly name is generally something provided to the app, but your app will still need to provide an admin key and generate an instance of the current SmartCardPinPolicy before passing all three values to RequestVirtualSmartCardCreationAsync.

  1. Crie uma nova instância de um SmartCardPinPolicyCreate a new instance of a SmartCardPinPolicy
  2. Gere o valor da chave de administração chamando CryptographicBuffer.GenerateRandom no valor da chave de administração fornecido pelo serviço ou pela ferramenta de gerenciamento.Generate the admin key value by calling CryptographicBuffer.GenerateRandom on the admin key value provided by the service or management tool.
  3. Passe esses valores junto com a cadeia FriendlyNameText para RequestVirtualSmartCardCreationAsync.Pass these values along with the FriendlyNameText string to RequestVirtualSmartCardCreationAsync.
SmartCardPinPolicy pinPolicy = new SmartCardPinPolicy();
pinPolicy.MinLength = 6;

IBuffer adminkey = CryptographicBuffer.GenerateRandom(24);

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

Depois que RequestVirtualSmartCardCreationAsync tiver retornado o objeto SmartCardProvisioning associado, o cartão inteligente virtual será provisionado e estará pronto para o uso.Once RequestVirtualSmartCardCreationAsync has returned the associated SmartCardProvisioning object, the virtual smart card is provisioned and ready for use.

Observação

Para criar um cartão inteligente virtual usando um aplicativo UWP, o usuário que está executando o aplicativo deve ser um membro do grupo Administradores.In order to create a virtual smart card using a UWP app, the user running the app must be a member of the administrators group. Se o usuário não for um membro do grupo Administradores, a criação do cartão inteligente virtual falhará.If the user is not a member of the administrators group, virtual smart card creation will fail.

Trate os desafios da autenticaçãoHandle authentication challenges

Para autenticar com cartões inteligentes ou cartões inteligentes virtuais, o seu aplicativo deve fornecer o comportamento para concluir os desafios entre os dados da chave de administração armazenados no cartão e os dados da chave de administração mantidos pelo servidor de autenticação ou pela ferramenta de gerenciamento.To authenticate with smart cards or virtual smart cards, your app must provide the behavior to complete challenges between the admin key data stored on the card, and the admin key data maintained by the authentication server or management tool.

O código a seguir mostra como dar suporte à autenticação de cartão inteligente para serviços ou modificação de detalhes do cartão físico ou virtual.The following code shows how to support smart card authentication for services or modification of physical or virtual card details. Se os dados gerados usando a chave de administração no cartão ("desafio") forem iguais aos dados da chave de administração fornecidos pelo servidor ou pela ferramenta de gerenciamento ("adminkey"), a autenticação será bem-sucedida.If the data generated using the admin key on the card ("challenge") is the same as the admin key data provided by the server or management tool ("adminkey"), authentication is successful.

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;
    }
}

Você verá esse código referenciado em todo o restante deste tópico enquanto revisamos como concluir a ação de autenticação e como aplicar mudanças nas informações do cartão inteligente e do cartão inteligente virtual.You will see this code referenced throughout the remainder of this topic was we review how to complete an authentication action, and how to apply changes to smart card and virtual smart card information.

Verifique a resposta de autenticação do cartão inteligente ou do cartão inteligente virtualVerify smart card or virtual smart card authentication response

Agora que temos a lógica definida para os desafios de autenticação, podemos nos comunicar com o leitor para acessar o cartão inteligente, ou então, acessar um cartão inteligente virtual para autenticação.Now that we have the logic for authentication challenges defined, we can communicate with the reader to access the smart card, or alternatively, access a virtual smart card for authentication.

  1. Para começar o desafio, chame GetChallengeContextAsync do objeto SmartCardProvisioning associado ao cartão inteligente.To begin the challenge, call GetChallengeContextAsync from the SmartCardProvisioning object associated with the smart card. Isso irá gerar uma instância do SmartCardChallengeContext, que contém o valor Challenge do cartão.This will generate an instance of SmartCardChallengeContext, which contains the card's Challenge value.

  2. Em seguida, passe o valor do desafio do cartão e a chave de administração fornecidos pelo serviço ou pela ferramenta de gerenciamento ao ChallengeResponseAlgorithm que definimos no exemplo anterior.Next, pass the card's challenge value and the admin key provided by the service or management tool to the ChallengeResponseAlgorithm that we defined in the previous example.

  3. VerifyResponseAsync retornará true se a autenticação for bem-sucedida.VerifyResponseAsync will return true if authentication is successful.

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);
}

Altere ou redefina um PIN do usuárioChange or reset a user PIN

Para alterar o PIN associado a um cartão inteligente:To change the PIN associated with a smart card:

  1. Acesse o cartão e gere o objeto SmartCardProvisioning associado.Access the card and generate the associated SmartCardProvisioning object.
  2. Chame RequestPinChangeAsync para exibir uma interface do usuário para que o usuário conclua essa operação.Call RequestPinChangeAsync to display a UI to the user to complete this operation.
  3. Se o PIN foi alterado com êxito, a chamada retornará true.If the PIN was successfully changed the call will return true.
SmartCardProvisioning provisioning =
    await SmartCardProvisioning.FromSmartCardAsync(card);

bool result = await provisioning.RequestPinChangeAsync();

Para solicitar uma redefinição de PIN:To request a PIN reset:

  1. Chame RequestPinResetAsync para iniciar a operação.Call RequestPinResetAsync to initiate the operation. Essa chamada inclui um método SmartCardPinResetHandler que representa o cartão inteligente e a solicitação de redefinição de PIN.This call includes a SmartCardPinResetHandler method that represents the smart card and the pin reset request.

  2. SmartCardPinResetHandler fornece informações de que nosso ChallengeResponseAlgorithm, encapsulado em uma chamada SmartCardPinResetDeferral, usa para comparar o valor do desafio do cartão e a chave de administração fornecida pelo serviço ou pela ferramenta de gerenciamento para autenticar a solicitação.SmartCardPinResetHandler provides information that our ChallengeResponseAlgorithm, wrapped in a SmartCardPinResetDeferral call, uses to compare the card's challenge value and the admin key provided by the service or management tool to authenticate the request.

  3. Se o desafio for bem-sucedido, a chamada RequestPinResetAsync estará concluída; retornando true se o PIN teve uma redefinição bem-sucedida.If the challenge is successful, the RequestPinResetAsync call is completed; returning true if the PIN was successfully reset.

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();
        }
    });
}

Remova um cartão inteligente ou um cartão inteligente virtualRemove a smart card or virtual smart card

Quando um cartão inteligente físico é removido, um evento CardRemoved é disparado quando o cartão é excluído.When a physical smart card is removed a CardRemoved event will fire when the card is deleted.

Associe o disparo desse evento ao leitor de cartão ao método que define o comportamento do seu aplicativo na remoção do cartão ou do leitor como um manipulador de eventos.Associate the firing of this event with the card reader with the method that defines your app's behavior on card or reader removal as an event handler. Esse comportamento pode ser algo tão simples quanto fornecer notificação ao usuário de que o cartão foi removido.This behavior can be something as simply as providing notification to the user that the card was removed.

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

A remoção de um cartão inteligente virtual é tratada de forma programática, primeiro recuperando o cartão e, em seguida, chamando RequestVirtualSmartCardDeletionAsync a partir do objeto retornado SmartCardProvisioning.The removal of a virtual smart card is handled programmatically by first retrieving the card and then calling RequestVirtualSmartCardDeletionAsync from the SmartCardProvisioning returned object.

bool result = await SmartCardProvisioning
    .RequestVirtualSmartCardDeletionAsync(card);