Я заметил, что все мои сертификаты смарт-карт имеют два свойства, которых нет у других сертификатов. Их можно запросить по телефону CertGetCertificateContextProperty
с CERT_SCARD_PIN_ID_PROP_ID
или CERT_SCARD_INFO_PROP_ID
. Я не знаю, является ли это окончательным, но это работает для меня.
В этом примере должны быть указаны только сертификаты смарт-карт:
class Program
{
[System.Runtime.InteropServices.DllImport("crypt32.dll", SetLastError = true)]
extern public static bool CertGetCertificateContextProperty(IntPtr pCertContext, Int32 dwPropId, IntPtr pvData, ref Int32 pcbData);
const int CERT_SCARD_PIN_ID_PROP_ID = 90;
const int CERT_SCARD_INFO_PROP_ID = 91;
static bool CertificateHasProperty(X509Certificate x509, int propId)
{
int cbData = 0;
// If the property exists CertGetCertificateContextProperty returns true
// and sets cbData to the size of buffer required to hold the data.
return CertGetCertificateContextProperty(x509.Handle, propId, IntPtr.Zero, ref cbData);
}
static void Main(string[] args)
{
X509Store store = new X509Store("MY", StoreLocation.CurrentUser);
store.Open(OpenFlags.ReadOnly | OpenFlags.OpenExistingOnly);
foreach (X509Certificate2 x509 in store.Certificates)
{
if (CertificateHasProperty(x509, CERT_SCARD_INFO_PROP_ID))
{
Console.WriteLine("Subject: " + x509.Subject);
}
}
}
}