private static bool HasHWToken(X509Certificate2 cert) { KEY_SPEC dwSpec = 0; bool keyFree = false; CryptAcquireCertificatePrivateKey(cert.Handle, CRYPT_ACQUIRE_PREFER_NCRYPT_KEY_FLAG | CRYPT_ACQUIRE_COMPARE_KEY_FLAG | CRYPT_ACQUIRE_SILENT_FLAG, IntPtr.Zero, out IntPtr key, ref dwSpec, ref keyFree); if (key == IntPtr.Zero) { return(false); } uint type = 0, typesize = 4, provsize = 4; byte[] tmp = new byte[4]; switch (dwSpec) { case KEY_SPEC.AT_KEYEXCHANGE: case KEY_SPEC.AT_SIGNATURE: CryptGetProvParam(key, PP_IMPTYPE, tmp, ref typesize, 0); type = BitConverter.ToUInt32(tmp, 0); if (keyFree) { CryptReleaseContext(key, 0); } break; case KEY_SPEC.CERT_NCRYPT_KEY_SPEC: NCryptGetProperty(key, NCRYPT_PROVIDER_HANDLE_PROPERTY, tmp, provsize, ref provsize, 0); IntPtr prov = new IntPtr(BitConverter.ToInt32(tmp, 0)); if (prov != IntPtr.Zero) { NCryptGetProperty(prov, NCRYPT_IMPL_TYPE_PROPERTY, tmp, typesize, ref typesize, 0); type = BitConverter.ToUInt32(tmp, 0); NCryptFreeObject(prov); } if (keyFree) { NCryptFreeObject(key); } break; } return((type & (CRYPT_IMPL_HARDWARE | CRYPT_IMPL_REMOVABLE)) > 0); }
private static extern bool CryptAcquireCertificatePrivateKey( IntPtr pCertContext, uint dwFlags, IntPtr pvParameters, out IntPtr phKey, ref KEY_SPEC pdwKeySpec, ref bool pfFree);