Tarjetas inteligentes
En este tema se explica cómo las aplicaciones de Windows pueden usar tarjetas inteligentes para conectar a los usuarios a servicios de red seguros, como cómo acceder a lectores de tarjetas inteligentes físicas, crear tarjetas inteligentes virtuales, comunicarse con tarjetas inteligentes, autenticar usuarios, restablecer PIN de usuario y quitar o desconectar tarjetas inteligentes.
Las API de Windows Runtime (WinRT) para tarjetas inteligentes forman parte del Kit de desarrollo de software (SDK) de Windows. Estas API se crearon para su uso en aplicaciones de Plataforma universal de Windows (UWP), pero también se pueden usar en aplicaciones winUI o en aplicaciones de escritorio empaquetadas, incluidas WPF y Windows Forms. Para obtener más información sobre el uso de las API de WinRT en la aplicación de escritorio de Windows, consulta Llamar a las API de Windows Runtime en aplicaciones de escritorio.
Configuración del manifiesto de la aplicación
Para que la aplicación pueda autenticar a los usuarios mediante tarjetas inteligentes o tarjetas inteligentes virtuales, debe establecer la funcionalidad Certificados de usuario compartidos en el archivo Package.appxmanifest del proyecto de su proyecto de WinUI o del proyecto de empaquetado.
Acceso a lectores de tarjetas conectadas y tarjetas inteligentes
Puede consultar lectores y tarjetas inteligentes conectadas pasando el identificador de dispositivo (especificado en DeviceInformation) al método SmartCardReader.FromIdAsync . Para acceder a las tarjetas inteligentes conectadas actualmente al dispositivo de lector devuelto, llame a 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();
}
También debes permitir que la aplicación observe eventos CardAdded mediante la implementación de un método para controlar el comportamiento de la aplicación en la inserción de tarjetas.
private void reader_CardAdded(SmartCardReader sender, CardAddedEventArgs args)
{
// A card has been inserted into the sender SmartCardReader.
}
A continuación, puedes pasar cada objeto SmartCard devuelto a SmartCardProvisioning para acceder a los métodos que permiten a la aplicación acceder a su configuración y personalizarla.
Creación de una tarjeta inteligente virtual
Para crear una tarjeta inteligente virtual mediante SmartCardProvisioning, la aplicación primero tendrá que proporcionar un nombre descriptivo, una clave de administrador y un SmartCardPinPolicy. El nombre descriptivo suele ser algo proporcionado a la aplicación, pero la aplicación seguirá necesitando proporcionar una clave de administrador y generar una instancia de SmartCardPinPolicy actual antes de pasar los tres valores a RequestVirtualSmartCardCreationAsync.
- Creación de una nueva instancia de SmartCardPinPolicy
- Genere el valor de clave de administrador llamando a CryptographicBuffer.GenerateRandom en el valor de clave de administrador proporcionado por el servicio o la herramienta de administración.
- Pase estos valores junto con la cadena FriendlyNameText a RequestVirtualSmartCardCreationAsync.
var pinPolicy = new SmartCardPinPolicy
{
MinLength = 6
};
IBuffer adminkey = CryptographicBuffer.GenerateRandom(24);
SmartCardProvisioning provisioning = await
SmartCardProvisioning.RequestVirtualSmartCardCreationAsync(
"Card friendly name",
adminkey,
pinPolicy);
Una vez que RequestVirtualSmartCardCreationAsync ha devuelto el objeto SmartCardProvisioning asociado, la tarjeta inteligente virtual se aprovisiona y está lista para su uso.
Nota:
Para crear una tarjeta inteligente virtual mediante una aplicación de Windows empaquetada, el usuario que ejecuta la aplicación debe ser miembro del grupo de administradores. Si el usuario no es miembro del grupo de administradores, se producirá un error en la creación de tarjetas inteligentes virtuales.
Control de los desafíos de autenticación
Para autenticarse con tarjetas inteligentes o tarjetas inteligentes virtuales, la aplicación debe proporcionar el comportamiento para completar los desafíos entre los datos de clave de administrador almacenados en la tarjeta y los datos de clave de administrador mantenidos por el servidor de autenticación o la herramienta de administración.
En el código siguiente se muestra cómo admitir la autenticación de tarjetas inteligentes para los servicios o la modificación de los detalles de la tarjeta física o virtual. Si los datos generados con la clave de administrador en la tarjeta ("desafío") son los mismos que los datos de la clave de administración proporcionados por el servidor o la herramienta de administración ("adminkey"), la autenticación se realiza correctamente.
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;
}
}
Verá que este código al que se hace referencia en el resto de este tema fue revisar cómo completar una acción de autenticación y cómo aplicar cambios en la información de tarjeta inteligente y tarjeta inteligente virtual.
Comprobación de la respuesta de autenticación de tarjeta inteligente o tarjeta inteligente virtual
Ahora que tenemos definida la lógica para los desafíos de autenticación, podemos comunicarnos con el lector para acceder a la tarjeta inteligente o, como alternativa, acceder a una tarjeta inteligente virtual para la autenticación.
- Para comenzar el desafío, llame a GetChallengeContextAsync desde el objeto SmartCardProvisioning asociado a la tarjeta inteligente. Esto generará una instancia de SmartCardChallengeContext, que contiene el valor challenge de la tarjeta.
- A continuación, pase el valor de desafío de la tarjeta y la clave de administrador proporcionada por el servicio o la herramienta de administración al ChallengeResponseAlgorithm que definimos en el ejemplo anterior.
- VerifyResponseAsync devolverá true si la autenticación se realiza correctamente.
bool verifyResult = false;
SmartCard card = await rootPage.GetSmartCard();
SmartCardProvisioning provisioning =
await SmartCardProvisioning.FromSmartCardAsync(card);
SmartCardChallengeContext context =
await provisioning.GetChallengeContextAsync();
IBuffer response = ChallengeResponseAlgorithm.CalculateResponse(
context.Challenge,
rootPage.AdminKey);
verifyResult = await context.VerifyResponseAsync(response);
Cambiar o restablecer un PIN de usuario
Para cambiar el PIN asociado a una tarjeta inteligente:
- Acceda a la tarjeta y genere el objeto SmartCardProvisioning asociado.
- Llame a RequestPinChangeAsync para mostrar una interfaz de usuario al usuario para completar esta operación.
- Si el PIN se cambió correctamente, la llamada devolverá true.
SmartCardProvisioning provisioning =
await SmartCardProvisioning.FromSmartCardAsync(card);
bool result = await provisioning.RequestPinChangeAsync();
Para solicitar un restablecimiento de PIN:
- Llame a RequestPinResetAsync para iniciar la operación. Esta llamada incluye un método SmartCardPinResetHandler que representa la tarjeta inteligente y la solicitud de restablecimiento de patillas.
- SmartCardPinResetHandler proporciona información que nuestro ChallengeResponseAlgorithm, encapsulado en una llamada a SmartCardPinResetDeferral , usa para comparar el valor de desafío de la tarjeta y la clave de administrador proporcionada por el servicio o la herramienta de administración para autenticar la solicitud.
- Si el desafío se realiza correctamente, se completa la llamada RequestPinResetAsync ; devuelve true si el PIN se restablece correctamente.
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();
}
});
}
Quitar una tarjeta inteligente o una tarjeta inteligente virtual
Cuando se quita una tarjeta inteligente física, se activará un evento CardRemoved cuando se elimine la tarjeta.
Asocie la activación de este evento con el lector de tarjetas con el método que define el comportamiento de la aplicación en la eliminación de tarjetas o lectores como controlador de eventos. Este comportamiento puede ser algo tan simple como proporcionar una notificación al usuario que se quitó la tarjeta.
reader = card.Reader;
reader.CardRemoved += HandleCardRemoved;
La eliminación de una tarjeta inteligente virtual se controla mediante programación recuperando primero la tarjeta y, a continuación, llamando a RequestVirtualSmartCardDeletionAsync desde el objeto devuelto SmartCardProvisioning .
bool result = await SmartCardProvisioning
.RequestVirtualSmartCardDeletionAsync(card);