Freigeben über


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.

Abrufen des Administratorschlüssels

Bevor Sie die Authentifizierung ausführen können, müssen Sie den Administratorschlüssel abrufen. Die Quelle des Administratorschlüssels hängt von Ihrem Szenario ab:

  • Verwenden Sie für virtuelle Smartcards, die Sie erstellt haben: Verwenden Sie denselben Administratorschlüssel, der während der Kartenerstellung generiert wurde (siehe abschnitt "Erstellen einer virtuellen Smartcard" oben). Sie sollten diesen Schlüssel sicher für die spätere Authentifizierungsverwendung speichern.
  • Für vorhandene physische oder virtuelle Smartcards: Der Administratorschlüssel wird in der Regel von der IT-Abteilung Ihrer Organisation, dem Kartenverwaltungssystem oder dem Dienst bereitgestellt, der die Karte ausgestellt hat.
  • Für Entwicklung/Tests: Sie können einen Testadministratorschlüssel mithilfe von CryptographicBuffer.GenerateRandom generieren, wie im folgenden Beispiel für die Erstellung virtueller Karten gezeigt.
// Example: Store the admin key from virtual card creation for later use
IBuffer adminkey = CryptographicBuffer.GenerateRandom(24);

// Store this key securely in your app (e.g., in app settings, secure storage, etc.)
// You'll need this same key for authentication operations

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

// Save the adminkey for future authentication
SaveAdminKeySecurely(adminkey);

Beispielmethoden für die Verwaltung von Administratorschlüsseln

Hier sind Beispielmethoden, die Sie zum sicheren Speichern und Abrufen von Administratorschlüsseln implementieren können:

// Example implementation for storing admin key securely
private void SaveAdminKeySecurely(IBuffer adminKey)
{
    // Convert to string for storage (consider encryption for production)
    string adminKeyString = CryptographicBuffer.EncodeToBase64String(adminKey);
    
    // Store in app settings (consider using Windows Credential Manager for production)
    ApplicationData.Current.LocalSettings.Values["SmartCardAdminKey"] = adminKeyString;
}

// Example implementation for retrieving stored admin key
private IBuffer GetStoredAdminKey()
{
    // Retrieve from app settings
    string adminKeyString = ApplicationData.Current.LocalSettings.Values["SmartCardAdminKey"] as string;
    
    if (string.IsNullOrEmpty(adminKeyString))
    {
        throw new InvalidOperationException("Admin key not found. Ensure the smart card was created by this app or the admin key was provided by your IT department.");
    }
    
    // Convert back to IBuffer
    return CryptographicBuffer.DecodeFromBase64String(adminKeyString);
}

Authentifizierungsalgorithmus

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

// Use the admin key that was either:
// 1. Generated during virtual card creation, or
// 2. Provided by your IT department/card management system
IBuffer adminKey = GetStoredAdminKey(); // Your method to retrieve the stored admin key

IBuffer response = ChallengeResponseAlgorithm.CalculateResponse(
    context.Challenge,
    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
        {
            // Use the same admin key from card creation or your secure storage
            IBuffer adminKey = GetStoredAdminKey(); // Your method to retrieve the stored admin key
            
            IBuffer response =
                ChallengeResponseAlgorithm.CalculateResponse(
                    request.Challenge,
                    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);