internal extern static bool CryptGetUserKey(SafeCryptProvHandle hCryptProv, uint pdwKeySpec, ref IntPtr hKey);
public static bool IsPrivateKeyExportable(X509Certificate cert) { bool exportable = false; SafeCryptProvHandle hProvider = null; IntPtr hKey = IntPtr.Zero; bool freeProvider = false; bool freeCryptKey = false; uint acquireFlags = 0; uint keySpec = 0; byte[] permissionBytes = null; if (CryptAcquireCertificatePrivateKey(cert.Handle, acquireFlags, IntPtr.Zero, out hProvider, ref keySpec, ref freeProvider)) { SafeGlobalAllocHandle pBytes = SafeGlobalAllocHandle.Empty(); int length = 0; try { if (CryptGetUserKey(hProvider, keySpec, ref hKey)) { freeCryptKey = true; if (CryptGetKeyParam(hKey, KP_PERMISSIONS, pBytes, ref length, 0)) { pBytes = new SafeGlobalAllocHandle(length); if (CryptGetKeyParam(hKey, KP_PERMISSIONS, pBytes, ref length, 0)) { permissionBytes = new byte[length]; pBytes.Copy(permissionBytes, 0, length); int cryptNum = BitConverter.ToInt32(permissionBytes, 0); exportable = ((cryptNum & CRYPT_EXPORT) != 0); } } } } finally { if (freeCryptKey) { CryptDestroyKey(hKey); } if (freeProvider && hProvider != null) { hProvider.Dispose(); hProvider = null; } if (pBytes != null) { pBytes.Dispose(); pBytes = null; } } } return(exportable); }
internal static extern bool CryptAcquireCertificatePrivateKey(IntPtr pCertContext, uint flags, IntPtr reserved, [Out] out SafeCryptProvHandle phCryptProv, ref uint pdwKeySpec, [MarshalAs(UnmanagedType.Bool)] ref bool pfCallerFreeProv);