'How to enumerate all possible keys that exist on a smartcard that is present in a reader with just UWP APIs?
Here are the constraints for my question: How to enumerate all possible keys that exist on a smartcard that is present in a reader with UWP APIs?
- Use just Universal Windows Program (UWP) APIs
I do have a C++ approach using NCryptOpenStorageProvider(MS_SMART_CARD_KEY_STORAGE_PROVIDER) and NCryptEnumKeys https://docs.microsoft.com/en-us/windows/win32/api/ncrypt/nf-ncrypt-ncryptenumkeys
I want to exclude keys that belong to a smartcard that is not physically present in a reader.
Generally approaches that iterate through certificates in Cert stores have failed for me because Windows pops up a dialog asking for a card to be inserted which is no longer available. Maybe there is a way to exclude certificates like that, but I don't know the way.
Consequently it seems that an approach of iterating the keys through a provider makes more sense.
oldnewthing (who deserves thanks for helpful posts through the years) has a https://github.com/microsoft/Windows-universal-samples/tree/main/Samples/SmartCard but it does not show this exact functionality.
https://docs.microsoft.com/en-us/windows/uwp/security/smart-cards explains how UWP can interact with smartcards, including APDU transfer, but does not explain how to iterate the asymmetric keys at a high level.
Thanks for advice in advance...
p.s. here is the type of code that looks at the Cert Store, and gets a key.
X509Store store = new X509Store("MY", StoreLocation.CurrentUser);
store.Open(OpenFlags.ReadOnly | OpenFlags.OpenExistingOnly);
X509Certificate2Collection certs = (X509Certificate2Collection)store.Certificates;
int n = certs.Count;
msg += " has " + n.ToString() + " keys: ";
foreach (X509Certificate2 cert in certs)
{
if (!cert.HasPrivateKey) continue;
RSACng rsaCng = (RSACng)cert.GetRSAPrivateKey();
if (null == rsaCng) continue;
if (rsaCng.Key.Provider != CngProvider.MicrosoftSmartCardKeyStorageProvider) continue;
msg += rsaCng.Key.KeyName + ", ";
}
but I don't know how to restrict it to just keys that are currently present.
Solution 1:[1]
You can enumerate the readers using SCard* functions, then set the pszScope
argument of the NCryptEnumKeys()
call to L"\\\\.\\<ReaderName>\\"
.
Caution: this parameter is documented as "unused; set to NULL" in MSDN!
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | Beat Bolli |