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

时间:2016-11-07 14:09:57

标签: c# windows ssl certificate x509certificate

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

  • x509.SerialNumber
  • x509.Issuer
  • x509.Subject
  • x509.HasPrivateKey

是否有任何财产可以证明证书是否可以出口?我找不到一个,但我对此很新。

2 个答案:

答案 0 :(得分:1)

如果它是RSA证书,您可以这样做:

RSACryptoServiceProvider rsa = cert.PrivateKey;
var isExportable = rsa.CspKeyContainerInfo.Exportable; 

答案 1 :(得分:1)

没有一种可靠的方法,因为你必须越过“独立于实现”到“依赖于实现”的边界 - 可导出性不是证书或密钥所固有的,而是密钥存储方式的函数

如果您只使用Windows,而且使用的是Windows XP或更早版本,则可以相当可靠地运行:

try
{
    ICspAsymmetricAlgorithm key = cert.PrivateKey;

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

return whateverYouWantUnknownToBe;

一旦您使用Vista或更新版本,就可以获得HasPrivateKey为真的证书,但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.

但是,最终,唯一的万无一失的方法就是真正尝试它。