c# - 如何判断 X.509 证书是否可导出?

标签 c# windows ssl certificate x509certificate

我有一个简单的 C# DotNet 控制台应用程序,用于枚举位置/商店中的证书。它显示如下内容:

  • x509.序列号
  • x509.Issuer
  • x509.主题
  • x509.HasPrivateKey

是否有任何属性可以判断证书是否可导出?我找不到,但我对此还很陌生。

最佳答案

没有可靠的方法来做到这一点,因为您必须跨越从“独立于实现”到“依赖于实现”的边界——可导出性不是证书或 key 所固有的,而是 key 存储方式的函数.

如果您只使用 Windows,并且您使用的是 Windows XP 或更早版本,这将相当可靠地工作:

try
{
    ICspAsymmetricAlgorithm key = cert.PrivateKey;

    if (key != null)
    {
        return key.CspKeyContainerInfo.Exportable;
    }
}
catch (CryptographicException) {}

return whateverYouWantUnknownToBe;

一旦您使用的是 Vista 或更新版本,则可以在 HasPrivateKey 为 true 的情况下获取证书,但 PrivateKey 会抛出“指定的提供商无效”异常,以变通您需要升级到 .NET 4.6。

// AllowExport says whether it can be exported in a PFX (encrypted key)
// AllowPlainTextExport says whether it can be exported as (e.g.) an RSAParameters structure
const CngExportPolicies RequiredPolicies = CngExportPolicies.AllowExport;

RSACng rsaCng = cert.GetRSAPrivateKey() as RSACng;

if (rsaCng != null)
{
    return (rsaCng.Key.ExportPolicy & RequiredPolicies) == RequiredPolicies;
}

// Requires 4.6.1
ECDsaCng ecdsaCng = cert.GetECDsaPrivateKey() as ECDsaCng;

if (ecdsaCng != null)
{
    return (ecdsaCng.Key.ExportPolicy & RequiredPolicies) == RequiredPolicies;
}

// Requires 4.6.2
DSACng dsaCng = cert.GetDSAPrivateKey() as DSACng;

if (dsaCng != null)
{
    return (dsaCng.Key.ExportPolicy & RequiredPolicies) == RequiredPolicies;
}

// previous code goes here.

但是,最终,唯一万无一失的方法就是实际尝试。

关于c# - 如何判断 X.509 证书是否可导出?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40467213/

相关文章:

php - 如何使用 SSL 向客户端发送安全数据

c# - WPF 验证无需更新数据源

c# - 尝试将流事件附加到 EventStore 会引发异常

c# - 将 winform 应用程序灰色化,打开的对话框除外

c# - 确定文件夹是否在 .NET 中共享

c++ - 创建命名管道时出现 GLE=5(拒绝访问)错误

c# - 查看 wcf 服务发回的数据大小

c++ - 如何在运行时检查 void* 是否为 IUnknown*?

SSL client-hello,消息体结构

linux - Nginx 返回 499