如何获取 X509Certificate2 的私钥,其中 oid 与 1.2.840..?



我使用提示命令创建了自签名证书

csptest -keyset -newkeyset -makecert -container test3 -keytype exchange

然后我使用第 3 方应用程序安装了它。当我尝试在核心应用程序中获取证书PrivateKeyasp.net 时,它会抛出NotSupportedException.

var store = new X509Store(StoreName.My, StoreLocation.CurrentUser);
store.Open(OpenFlags.ReadOnly);
certificates = store1.Certificates;
var certificate = GetCertificateByThumbprint(certificates, "51F9748FE7DDE895DD100AAD0BE54C1ACF6B4DCC");
if (certificate.HasPrivateKey)
{
var kayAlgorithm = = _certificate.GetKeyAlgorithm(); // same as certificate.PublicKey.Oid.Value;
var rsaPrivateKey = certificate.GetRSAPrivateKey();
var dsaPrivateKey = _certificate.GetDSAPrivateKey();
var ecdsaPrivateKey = _certificate.GetECDsaPrivateKey();
var privateKey = certificate.PrivateKey;
}

HasPrivateKey返回 true。GetRSAPrivateKeyGetDSAPrivateKeyGetECDsaPrivateKey返回空值。但是GetKeyAlgorithm(oid.value( 返回"1.2.643.7.1.1.1.1"。我更深入地研究了System.Security.Cryptography.X509Certificates.X509Certificate2库,发现那里只有硬编码检查"1.2.840.113549.1.1.1"或"1.2.840.10040.4.1"算法。

public AsymmetricAlgorithm PrivateKey
{
get
{
this.ThrowIfInvalid();
if (!this.HasPrivateKey)
return (AsymmetricAlgorithm) null;
if (this._lazyPrivateKey == null)
{
string keyAlgorithm = this.GetKeyAlgorithm();
if (!(keyAlgorithm == "1.2.840.113549.1.1.1"))
{
if (!(keyAlgorithm == "1.2.840.10040.4.1"))
throw new NotSupportedException(SR.NotSupported_KeyAlgorithm);
this._lazyPrivateKey = (AsymmetricAlgorithm) this.Pal.GetDSAPrivateKey();
}
else
this._lazyPrivateKey = (AsymmetricAlgorithm) this.Pal.GetRSAPrivateKey();
}
return this._lazyPrivateKey;
}
set
{
throw new PlatformNotSupportedException();
}
}

在.net框架中,获取PrivateKey会引发相同的异常。System.Security.Cryptography.X509Certificates.X509Certificate2看起来不一样。

public AsymmetricAlgorithm PrivateKey
{
get
{
if (!this.HasPrivateKey)
return (AsymmetricAlgorithm) null;
if (this.m_privateKey == null)
{
CspParameters parameters = new CspParameters();
if (!X509Certificate2.GetPrivateKeyInfo(this.m_safeCertContext, ref parameters))
return (AsymmetricAlgorithm) null;
parameters.Flags |= CspProviderFlags.UseExistingKey;
switch (this.PublicKey.AlgorithmId)
{
case 8704:
this.m_privateKey = (AsymmetricAlgorithm) new DSACryptoServiceProvider(parameters);
break;
case 9216:
case 41984:
this.m_privateKey = (AsymmetricAlgorithm) new RSACryptoServiceProvider(parameters);
break;
default:
throw new NotSupportedException(SR.GetString("NotSupported_KeyAlgorithm"));
}
}
return this.m_privateKey;
}
set
{
...
}
}

那么,我怎样才能获得不同算法的PrivateKey,或者我以前做错了什么?

GetCertificateByThumbprint方法源代码以防万一。(我无法使用X509Certificate2Collection.Find方法,因为它无效,因此不会返回我的证书(

private X509Certificate2 GetCertificateByThumbprint(X509Certificate2Collection certifcates, string thumbprint)
{
foreach (var certificate in certifcates)
{
if (certificate.Thumbprint == thumbprint)
return certificate;
}
}

由于 .NET 没有 GOST 的表示形式,因此 PrivateKey 属性实际上没有任何有用的内容(如果它尚未被有效弃用(。

从 X509Certificate2 对象中,可以读取Handle属性以获取基础操作系统值(Windows 上的PCERT_CONTEXT(。 然后,您可以使用它来P/Invoke到操作系统函数中,例如CryptAcquireCertificatePrivateKey。假设 GOST CSP 已在 Windows 中注册,该函数应成功返回 CAPI 或 CNG 密钥句柄(由 dwKeySpec 返回确定(,然后需要继续将其与 P/Invokes 一起使用(可能通过您创建的 GOST 类来管理它(。

相关内容

  • 没有找到相关文章

最新更新