Smartcards

In diesem Thema wird erläutert, wie Windows-Apps Smartcards verwenden können, um Benutzer mit sicheren Netzwerkdiensten zu verbinden, wie Sie auf physische Smartcardleser zugreifen, virtuelle Smartcards erstellen, mit Smartcards kommunizieren, Benutzer authentifizieren, Benutzer-PINs zurücksetzen und Smartcards entfernen oder trennen.

Die Windows-Runtime (WinRT)-APIs für Smartcards sind Teil des Windows Software Development Kit (SDK). Diese APIs wurden für die Verwendung in Universelle Windows-Plattform (UWP)-Apps erstellt, können aber auch in WinUI-Apps oder in verpackten Desktop-Apps verwendet werden, einschließlich WPF und Windows Forms. Weitere Informationen zur Verwendung von WinRT-APIs in Ihrer Windows-Desktop-App finden Sie unter Aufrufen Windows-Runtime APIs in Desktop-Apps.

Konfigurieren des App-Manifests

Bevor Ihre App Benutzer mithilfe von Smartcards oder virtuellen Smartcards authentifizieren kann, müssen Sie die Funktion "Freigegebene Benutzerzertifikate " in der Datei "Package.appxmanifest" des WinUI-Projekts oder des Paketprojekts festlegen.

Zugreifen auf verbundene Kartenleser und Smartcards

Sie können Leser und angefügte Smartcards abfragen, indem Sie die Geräte-ID (in DeviceInformation angegeben) an die SmartCardReader.FromIdAsync-Methode übergeben. Rufen Sie SmartCardReader.FindAllCardsAsync auf, um auf die aktuell an das zurückgegebene Lesegerät angeschlossenen Smartcards zuzugreifen.

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

Außerdem sollten Sie es Ihrer App ermöglichen, kartenadded-Ereignisse zu beobachten, indem Sie eine Methode zum Behandeln des App-Verhaltens beim Einfügen von Karten implementieren.

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

Anschließend können Sie jedes zurückgegebene SmartCard-Objekt an SmartCardProvisioning übergeben, um auf die Methoden zuzugreifen, mit denen Ihre App auf die Konfiguration zugreifen und diese anpassen kann.

Erstellen einer virtuellen Smartcard

Um eine virtuelle Smartcard mit SmartCardProvisioning zu erstellen, muss Ihre App zunächst einen Anzeigenamen, einen Administratorschlüssel und eine SmartCardPinPolicy angeben. Der Anzeigename wird in der Regel für die App bereitgestellt, ihre App muss jedoch dennoch einen Administratorschlüssel bereitstellen und eine Instanz der aktuellen SmartCardPinPolicy generieren, bevor alle drei Werte an RequestVirtualSmartCardCreationAsync übergeben werden.

  1. Erstellen einer neuen Instanz einer SmartCardPinPolicy
  2. Generieren Sie den Wert des Administratorschlüssels, indem Sie CryptographicBuffer.GenerateRandom für den vom Dienst oder Verwaltungstool bereitgestellten Administratorschlüsselwert aufrufen.
  3. Übergeben Sie diese Werte zusammen mit der FriendlyNameText-Zeichenfolge an RequestVirtualSmartCardCreationAsync.
var pinPolicy = new SmartCardPinPolicy
    {
        MinLength = 6
    };

IBuffer adminkey = CryptographicBuffer.GenerateRandom(24);

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

Sobald RequestVirtualSmartCardCreationAsync das zugeordnete SmartCardProvisioning-Objekt zurückgegeben hat, wird die virtuelle Smartcard bereitgestellt und kann verwendet werden.

Hinweis

Um eine virtuelle Smartcard mit einer verpackten Windows-App zu erstellen, muss der Benutzer, der die App ausführt, Mitglied der Administratorgruppe sein. Wenn der Benutzer kein Mitglied der Gruppe "Administratoren" ist, schlägt die Erstellung virtueller Smartcards fehl.

Behandeln von Authentifizierungsproblemen

Um sich bei Smartcards oder virtuellen Smartcards zu authentifizieren, muss Ihre App das Verhalten bereitstellen, um Probleme zwischen den auf der Karte gespeicherten Administratorschlüsseldaten und den vom Authentifizierungsserver oder Verwaltungstool verwalteten Administratorschlüsseldaten auszuführen.

Der folgende Code zeigt, wie Die Smartcard-Authentifizierung für Dienste oder Änderungen von physischen oder virtuellen Kartendetails unterstützt wird. Wenn die mit dem Administratorschlüssel auf der Karte generierten Daten ("Abfrage") mit den vom Server oder Verwaltungstool bereitgestellten Administratorschlüsseldaten ("Adminkey") identisch sind, ist die Authentifizierung erfolgreich.

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

Dieser Code, auf den im restlichen Teil dieses Themas verwiesen wird, sehen Sie, wie eine Authentifizierungsaktion abgeschlossen wird, und wie Änderungen auf Smartcard- und virtuelle Smartcardinformationen angewendet werden.

Überprüfen der Smartcard- oder virtuellen Smartcard-Authentifizierungsantwort

Da nun die Logik für Authentifizierungsprobleme definiert ist, können wir mit dem Leser kommunizieren, um auf die Smartcard zuzugreifen oder alternativ auf eine virtuelle Smartcard für die Authentifizierung zuzugreifen.

  1. Rufen Sie getChallengeContextAsync aus dem SmartCardProvisioning-Objekt auf, das der Smartcard zugeordnet ist, um die Herausforderung zu starten. Dadurch wird eine Instanz von SmartCardChallengeContext generiert, die den Challenge-Wert der Karte enthält.
  2. Übergeben Sie als Nächstes den Abfragewert der Karte und den vom Dienst oder Verwaltungstool bereitgestellten Administratorschlüssel an die ChallengeResponseAlgorithm , die wir im vorherigen Beispiel definiert haben.
  3. VerifyResponseAsync gibt true zurück, wenn die Authentifizierung erfolgreich ist.
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);

Ändern oder Zurücksetzen einer Benutzer-PIN

So ändern Sie die pin, die einer Smartcard zugeordnet ist:

  1. Greifen Sie auf die Karte zu und generieren Sie das zugeordnete SmartCardProvisioning-Objekt .
  2. Rufen Sie RequestPinChangeAsync auf, um dem Benutzer eine Benutzeroberfläche anzuzeigen, um diesen Vorgang abzuschließen.
  3. Wenn die PIN erfolgreich geändert wurde, gibt der Aufruf "true" zurück.
SmartCardProvisioning provisioning =
    await SmartCardProvisioning.FromSmartCardAsync(card);

bool result = await provisioning.RequestPinChangeAsync();

So fordern Sie eine PIN-Zurücksetzung an:

  1. Rufen Sie RequestPinResetAsync auf, um den Vorgang zu initiieren. Dieser Aufruf enthält eine SmartCardPinResetHandler-Methode , die die Smartcard und die Pin-Zurücksetzungsanforderung darstellt.
  2. SmartCardPinResetHandler stellt Informationen bereit, die unser ChallengeResponseAlgorithm, das in einen SmartCardPinResetDeferral-Aufruf eingeschlossen ist, verwendet, um den Abfragewert der Karte und den vom Dienst oder Verwaltungstool bereitgestellten Administratorschlüssel zu vergleichen, um die Anforderung zu authentifizieren.
  3. Wenn die Abfrage erfolgreich ist, wird der RequestPinResetAsync-Aufruf abgeschlossen. "true ", wenn die PIN erfolgreich zurückgesetzt wurde.
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();
        }
    });
}

Entfernen einer Smartcard oder einer virtuellen Smartcard

Wenn eine physische Smartcard entfernt wird, wird ein CardRemoved-Ereignis ausgelöst, wenn die Karte gelöscht wird.

Ordnen Sie das Auslösen dieses Ereignisses dem Kartenleser der Methode zu, die das Verhalten Ihrer App beim Entfernen von Karten oder Lesern als Ereignishandler definiert. Dieses Verhalten kann so einfach wie das Bereitstellen von Benachrichtigungen für den Benutzer sein, dass die Karte entfernt wurde.

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

Das Entfernen einer virtuellen Smartcard wird programmgesteuert behandelt, indem zuerst die Karte abgerufen und dann RequestVirtualSmartCardDeletionAsync aus dem zurückgegebenen SmartCardProvisioning-Objekt aufgerufen wird.

bool result = await SmartCardProvisioning
    .RequestVirtualSmartCardDeletionAsync(card);