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

本文关键字:是否 证书 何判断 判断 | 更新日期: 2023-09-27 18:16:36

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

  • x509。SerialNumber
  • x509。发行人
  • x509。主题
  • x509。HasPrivateKey

是否有任何属性可以告诉证书是否可导出?

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

没有可靠的方法可以做到这一点,因为您必须跨越从"独立于实现"到"依赖于实现"的界限——可导出性不是证书或密钥所固有的,而是密钥存储方式的一个函数。

如果你的操作系统是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.

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

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

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