From 27bd33e6f9064138fd14b319161ac713fced4229 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 26 Aug 2025 13:46:37 +0000 Subject: [PATCH 1/3] Initial plan From 9336ab7894e79d1fed2e091a2e1096453252150a Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 26 Aug 2025 13:57:34 +0000 Subject: [PATCH 2/3] Fix smart cards authentication example - show how to obtain adminKey Co-authored-by: alvinashcraft <73072+alvinashcraft@users.noreply.github.com> --- hub/apps/develop/security/smart-cards.md | 70 +++++++++++++++++++++++- 1 file changed, 68 insertions(+), 2 deletions(-) diff --git a/hub/apps/develop/security/smart-cards.md b/hub/apps/develop/security/smart-cards.md index 674d668528..4051f58620 100644 --- a/hub/apps/develop/security/smart-cards.md +++ b/hub/apps/develop/security/smart-cards.md @@ -84,6 +84,64 @@ Once [RequestVirtualSmartCardCreationAsync](/uwp/api/windows.devices.smartcards. 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. +### Obtaining the admin key + +Before you can perform authentication, you need to obtain the admin key. The source of the admin key depends on your scenario: + +- **For virtual smart cards you created**: Use the same admin key that was generated during card creation (as shown in the "Create a virtual smart card" section above). You should store this key securely for later authentication use. +- **For existing physical or virtual smart cards**: The admin key is typically provided by your organization's IT department, card management system, or the service that issued the card. +- **For development/testing**: You can generate a test admin key using `CryptographicBuffer.GenerateRandom(24)` as shown in the virtual card creation example. + +```cs +// 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); +``` + +### Example admin key management methods + +Here are example methods you might implement to securely store and retrieve admin keys: + +```cs +// 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); +} +``` + +### Authentication algorithm + The following code shows 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. ```cs @@ -123,9 +181,14 @@ SmartCardProvisioning provisioning = 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, - rootPage.AdminKey); + adminKey); verifyResult = await context.VerifyResponseAsync(response); ``` @@ -163,10 +226,13 @@ bool result = await provisioning.RequestPinResetAsync( 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, - rootPage.AdminKey); + adminKey); request.SetResponse(response); } finally From f1dc3f637f2ab61abf20631b7ae5940c364d4d58 Mon Sep 17 00:00:00 2001 From: Alvin Ashcraft <73072+alvinashcraft@users.noreply.github.com> Date: Tue, 26 Aug 2025 10:06:04 -0400 Subject: [PATCH 3/3] Update hub/apps/develop/security/smart-cards.md --- hub/apps/develop/security/smart-cards.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hub/apps/develop/security/smart-cards.md b/hub/apps/develop/security/smart-cards.md index 4051f58620..6b555e093d 100644 --- a/hub/apps/develop/security/smart-cards.md +++ b/hub/apps/develop/security/smart-cards.md @@ -90,7 +90,7 @@ Before you can perform authentication, you need to obtain the admin key. The sou - **For virtual smart cards you created**: Use the same admin key that was generated during card creation (as shown in the "Create a virtual smart card" section above). You should store this key securely for later authentication use. - **For existing physical or virtual smart cards**: The admin key is typically provided by your organization's IT department, card management system, or the service that issued the card. -- **For development/testing**: You can generate a test admin key using `CryptographicBuffer.GenerateRandom(24)` as shown in the virtual card creation example. +- **For development/testing**: You can generate a test admin key using [CryptographicBuffer.GenerateRandom](/uwp/api/windows.security.cryptography.cryptographicbuffer.generaterandom) as shown in the virtual card creation example below. ```cs // Example: Store the admin key from virtual card creation for later use