Language: HTML | XAML

How to authenticate with smart cards and virtual smart cards (XAML)

Starting with Windows 8.1 your app can communicate with smart card readers and connected smart cards, or create virtual smart cards, to authenticate users for access to secure network services. The APIs that make this possible are defined in the Windows.Devices.SmartCards namespace.

This topic will show you how to access a physical smart card or create a new virtual smart card. Then

What you need to know

Technologies

Prerequisites

This topic and the provided code examples directly reference the Windows 8.1 Smart card sample. In addition to referencing the new Windows.Devices.SmartCards namespace, the creation of admin keys for virtual smart cards also includes some APIs defined by the Windows.Security.Cryptography namespace.

Important  Before your Windows Store app development can authenticate users using smart cards or virtual smart cards, you must set the Shared User Certificates capability in the project Package.appxmanifest file.

Access connected card readers and smart cards

You can query for readers and attached smart cards by passing the device ID (specified in DeviceInformation) to the SmartCardReader.FromIdAsync method. 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();
}

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


You can then pass each returned SmartCard object to SmartCardProvisioning to access the methods that allow your app to access and customize its configuration.

Create a virtual smart card

To create a virtual smart card using SmartCardProvisioning, your app will first need to provide a friendly name, an admin key, and a SmartCardPinPolicy. 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. Create a new instance of a SmartCardPinPolicy
  2. Generate the admin key value by calling CryptographicBuffer.GenerateRandom on the admin key value provided by the service or management tool.
  3. 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);

Once RequestVirtualSmartCardCreationAsync has returned the associated SmartCardProvisioning object, the virtual smart card is provisioned and ready for use.

Handle authentication challenges

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.

The following code is an example of how to support smart card authentication for services or modification of physical or virtual card details. 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;
	}
}

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.

Verify smart card or virtual smart card authentication response

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. To begin the challenge, call GetChallengeContextAsync from the SmartCardProvisioning object associated with the smart card. This will generate an instance of SmartCardChallengeContext, which contains the card's Challenge value.

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

Change or reset a user PIN

To change the PIN associated with a smart card:

  1. Access the card and generate the associated SmartCardProvisioning object.
  2. Call RequestPinChangeAsync to display a UI to the user to complete this operation.
  3. If the PIN was successfully changed the call will return true.


SmartCardProvisioning provisioning =
	await SmartCardProvisioning.FromSmartCardAsync(card);

bool result = await provisioning.RequestPinChangeAsync();

To request a PIN reset:

  1. Call RequestPinResetAsync to initiate the operation. This call includes a SmartCardPinResetHandler method that represents the smart card and the pin reset request.
  2. 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. 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();
		}
	});
}

Remove a smart card or virtual smart card

When a physical smart card is removed a CardRemoved event will fire when the card is deleted.

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. This behavior can be something as simply as providing notification to the user that the card was removed.



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


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


 

 

Show:
© 2015 Microsoft