Intelligens kártyák

Ez a témakör azt ismerteti, hogy a Windows-alkalmazások hogyan használhatnak intelligens kártyákat a felhasználók biztonságos hálózati szolgáltatásokhoz való csatlakoztatásához, beleértve a fizikai intelligens kártyaolvasók elérését, a virtuális intelligens kártyák létrehozását, az intelligens kártyákkal való kommunikációt, a felhasználók hitelesítését, a felhasználói PIN-kódok alaphelyzetbe állítását, valamint az intelligens kártyák eltávolítását vagy leválasztását.

Az intelligens kártyákHoz készült Windows Runtime (WinRT) API-k a Windows Software Development Kit (SDK) részét képezik. Ezek az API-k a WinUI-ban és más asztali alkalmazásokban, például a WPF-ben és a WinForm-ban is használhatók. A WinRT API-k windowsos asztali alkalmazásban való használatáról további információt a Windows futtatókörnyezeti API-k meghívása asztali alkalmazásokban című témakörben talál.

Az alkalmazásjegyzék konfigurálása

Mielőtt az alkalmazás intelligens kártyákkal vagy virtuális intelligens kártyákkal hitelesítené a felhasználókat, be kell állítania a Megosztott felhasználói tanúsítványok funkciót a WinUI-projekt vagy a csomagolási projekt Package.appxmanifest fájljában.

Csatlakoztatott kártyaolvasók és intelligens kártyák elérése

Lekérdezheti az olvasókat és a csatolt intelligens kártyákat úgy, hogy átadja az eszközazonosítót (a DeviceInformationban megadva) a SmartCardReader.FromIdAsync metódusnak. A visszaadott olvasóeszközhöz jelenleg csatlakoztatott intelligens kártyák eléréséhez hívja meg a SmartCardReader.FindAllCardsAsync parancsot.

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

Azt is engedélyeznie kell, hogy az alkalmazás megfigyelje a CardAdded eseményeket egy olyan módszer implementálásával, amely kezeli az alkalmazás viselkedését a kártya beszúrásakor.

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

Ezután minden visszaadott SmartCard-objektumot átadhat a SmartCardProvisioningnek , hogy hozzáférhessen azokhoz a módszerekhez, amelyek lehetővé teszik az alkalmazás számára a konfiguráció elérését és testreszabását.

Virtuális intelligens kártya létrehozása

Ahhoz, hogy a SmartCardProvisioning használatával virtuális intelligens kártyát hozzon létre, az alkalmazásnak először meg kell adnia egy rövid nevet, egy rendszergazdai kulcsot és egy SmartCardPinPolicy-t. A rövid név általában az alkalmazásnak van megadva, de az alkalmazásnak továbbra is meg kell adnia egy rendszergazdai kulcsot, és létre kell hoznia az aktuális SmartCardPinPolicy egy példányát, mielőtt mindhárom értéket átadja a RequestVirtualSmartCardCreationAsyncnek.

  1. SmartCardPinPolicy új példányának létrehozása
  2. Hozza létre a rendszergazdai kulcs értékét a CryptographicBuffer.GenerateRandom meghívásával a szolgáltatás vagy a felügyeleti eszköz által biztosított rendszergazdai kulcsértéken.
  3. Adja át ezeket az értékeket a FriendlyNameTextsztringgel együtt a RequestVirtualSmartCardCreationAsyncnek.
var pinPolicy = new SmartCardPinPolicy
    {
        MinLength = 6
    };

IBuffer adminkey = CryptographicBuffer.GenerateRandom(24);

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

Miután a RequestVirtualSmartCardCreationAsync visszaadta a társított SmartCardProvisioning objektumot, a virtuális intelligens kártya ki van építve és használatra kész.

Megjegyzés:

Ahhoz, hogy egy csomagolt Windows-alkalmazással virtuális intelligens kártyát hozzon létre, az alkalmazást futtató felhasználónak a rendszergazdai csoport tagjának kell lennie. Ha a felhasználó nem tagja a rendszergazdák csoportjának, a virtuális intelligens kártya létrehozása sikertelen lesz.

Hitelesítési kihívások kezelése

Az intelligens kártyákkal vagy virtuális intelligens kártyákkal történő hitelesítéshez az alkalmazásnak biztosítania kell a viselkedést a kártyán tárolt rendszergazdai kulcsadatok és a hitelesítési kiszolgáló vagy a felügyeleti eszköz által kezelt rendszergazdai kulcsadatok közötti kihívások teljesítéséhez.

A rendszergazdai kulcs beszerzése

A hitelesítés előtt be kell szereznie a rendszergazdai kulcsot. A rendszergazdai kulcs forrása a forgatókönyvtől függ:

  • A létrehozott virtuális intelligens kártyák esetében: Használja ugyanazt a rendszergazdai kulcsot, amelyet a kártya létrehozásakor hoztak létre (a fenti "Virtuális intelligens kártya létrehozása" szakaszban látható módon). Ezt a kulcsot biztonságosan kell tárolni a későbbi hitelesítéshez.
  • Meglévő fizikai vagy virtuális intelligens kártyák esetén: A rendszergazdai kulcsot általában a szervezet informatikai részlege, a kártyakezelő rendszer vagy a kártyát kibocsátó szolgáltatás biztosítja.
  • Fejlesztéshez/teszteléshez: Létrehozhat egy teszt rendszergazdai kulcsot a CryptographicBuffer.GenerateRandom használatával, ahogyan az alábbi virtuáliskártya-létrehozási példában látható.
// 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);

Példa rendszergazdai kulcskezelési módszerekre

A rendszergazdai kulcsok biztonságos tárolásához és lekéréséhez az alábbi példamódszerek implementálhatnak:

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

Hitelesítési algoritmus

Az alábbi kód bemutatja, hogyan támogathatja az intelligens kártya hitelesítését a szolgáltatásokhoz, illetve hogyan módosíthatja a fizikai vagy virtuális kártya adatait. Ha a kártyán található rendszergazdai kulccsal létrehozott adatok ("kihívás") megegyeznek a kiszolgáló vagy a felügyeleti eszköz ("adminkey") által biztosított rendszergazdai kulcsadatokkal, a hitelesítés sikeres lesz.

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

A témakör hátralévő részében erre a kódra hivatkozunk, miközben áttekintjük, hogyan hajthat végre hitelesítési műveletet, és hogyan alkalmazhat módosításokat az okoskártya és a virtuális okoskártya adataira.

Intelligens kártya vagy virtuális intelligenskártya-hitelesítési válasz ellenőrzése

Most, hogy meghatároztuk a hitelesítési kihívások logikáját, kommunikálhatunk az olvasóval az intelligens kártyához való hozzáféréshez, vagy másik lehetőségként egy virtuális intelligens kártyához való hozzáféréshez a hitelesítéshez.

  1. A feladat megkezdéséhez hívja meg a GetChallengeContextAsync parancsot az intelligens kártyához társított SmartCardProvisioning objektumból. Ez létrehozza a SmartCardChallengeContext egy példányát, amely tartalmazza a kártya Challenge értékét.
  2. Ezután adja át a kártya kihívásértékét és a szolgáltatás vagy felügyeleti eszköz által biztosított rendszergazdai kulcsot az előző példában definiált ChallengeResponseAlgorithm-nek .
  3. A VerifyResponseAsyncigaz értéket ad vissza, ha a hitelesítés sikeres.
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);

Felhasználói PIN-kód módosítása vagy alaphelyzetbe állítása

Az intelligens kártyához társított PIN-kód módosítása:

  1. Hozzáférés a kártyához, és hozza létre a társított SmartCardProvisioning objektumot.
  2. Hívja meg a RequestPinChangeAsync parancsot, hogy megjelenítsen egy felhasználói felületet a felhasználónak a művelet végrehajtásához.
  3. Ha a PIN-kód módosítása sikeresen megtörtént, a hívás igaz lesz.
SmartCardProvisioning provisioning =
    await SmartCardProvisioning.FromSmartCardAsync(card);

bool result = await provisioning.RequestPinChangeAsync();

PIN-kód alaphelyzetbe állításának kérése:

  1. Hívja meg a RequestPinResetAsync parancsot a művelet elindításához. Ez a hívás egy SmartCardPinResetHandler metódust tartalmaz, amely az intelligens kártyát és a pin-kód alaphelyzetbe állítási kérését jelöli.
  2. A SmartCardPinResetHandler információval szolgál arról, hogy a SmartCardPinResetDeferral hívásba csomagolt ChallengeResponseAlgorithm a kártya kihívásértékének és a szolgáltatás vagy felügyeleti eszköz által biztosított rendszergazdai kulcsnak a kérés hitelesítéséhez való összehasonlítására szolgál.
  3. Ha a feladat sikeres, a RequestPinResetAsync hívás befejeződött; igaz értéket ad vissza, ha a PIN-kód alaphelyzetbe állítása sikeresen megtörtént.
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();
        }
    });
}

Intelligens kártya vagy virtuális intelligens kártya eltávolítása

A fizikai intelligens kártya eltávolításakor a CardRemoved esemény aktiválódik a kártya törlésekor.

Társítsa az esemény aktiválását a kártyaolvasóhoz azzal a módszerrel, amely eseménykezelőként határozza meg az alkalmazás viselkedését a kártya- vagy olvasóeltávolításkor. Ez a viselkedés olyan lehet, mint a felhasználó értesítése arról, hogy a kártyát eltávolították.

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

A virtuális intelligens kártya eltávolítását programozott módon kezeli a rendszer, ha először beolvassa a kártyát, majd meghívja a RequestVirtualSmartCardDeletionAsync parancsot a SmartCardProvisioning visszaadott objektumból.

bool result = await SmartCardProvisioning
    .RequestVirtualSmartCardDeletionAsync(card);