如何判断 X.509 证书是否可导出?
How to tell if X.509 Certificate is Exportable?
我有一个简单的 C# DotNet 控制台应用程序,它在 location/store 中枚举证书。它显示如下内容:
- x509.SerialNumber
- x509.Issuer
- x509.Subject
- x509.HasPrivateKey
是否有 属性 可以判断证书是否可导出?我找不到,但我对此还很陌生。
如果是 RSA 证书,您可以这样做:
RSACryptoServiceProvider rsa = cert.PrivateKey;
var isExportable = rsa.CspKeyContainerInfo.Exportable;
没有可靠的方法,因为您必须跨越从 "implementation independent" 到 "implementation dependent" 的边界——可导出性不是证书或密钥所固有的,而是如何密钥已存储。
如果您只使用 Windows,并且您使用的是 Windows XP 或更早版本,这将相当可靠地工作:
try
{
ICspAsymmetricAlgorithm key = cert.PrivateKey;
if (key != null)
{
return key.CspKeyContainerInfo.Exportable;
}
}
catch (CryptographicException) {}
return whateverYouWantUnknownToBe;
一旦您使用的是 Vista 或更新版本,则可以获得证书,其中 HasPrivateKey
为真,但 PrivateKey
会引发 "invalid provider specified" 异常,以解决您需要的问题跳转到 .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# DotNet 控制台应用程序,它在 location/store 中枚举证书。它显示如下内容:
- x509.SerialNumber
- x509.Issuer
- x509.Subject
- x509.HasPrivateKey
是否有 属性 可以判断证书是否可导出?我找不到,但我对此还很陌生。
如果是 RSA 证书,您可以这样做:
RSACryptoServiceProvider rsa = cert.PrivateKey;
var isExportable = rsa.CspKeyContainerInfo.Exportable;
没有可靠的方法,因为您必须跨越从 "implementation independent" 到 "implementation dependent" 的边界——可导出性不是证书或密钥所固有的,而是如何密钥已存储。
如果您只使用 Windows,并且您使用的是 Windows XP 或更早版本,这将相当可靠地工作:
try
{
ICspAsymmetricAlgorithm key = cert.PrivateKey;
if (key != null)
{
return key.CspKeyContainerInfo.Exportable;
}
}
catch (CryptographicException) {}
return whateverYouWantUnknownToBe;
一旦您使用的是 Vista 或更新版本,则可以获得证书,其中 HasPrivateKey
为真,但 PrivateKey
会引发 "invalid provider specified" 异常,以解决您需要的问题跳转到 .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.
但是,最终,唯一万无一失的方法就是实际尝试。