C# 如何获取X509Certificate2的私钥(oid不同于1.2.840…)。。。。?

C# 如何获取X509Certificate2的私钥(oid不同于1.2.840…)。。。。?,c#,asp.net-core,x509certificate,x509certificate2,C#,Asp.net Core,X509certificate,X509certificate2,我已使用提示命令创建了自签名证书 csptest -keyset -newkeyset -makecert -container test3 -keytype exchange 然后我使用第三方应用程序安装了它。当我试图在asp.net核心应用程序中获取证书PrivateKey时,它抛出NotSupportedException var store=new X509Store(StoreName.My,StoreLocation.CurrentUser); 打开(OpenFlags.ReadO

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

csptest -keyset -newkeyset -makecert -container test3 -keytype exchange
然后我使用第三方应用程序安装了它。当我试图在asp.net核心应用程序中获取证书
PrivateKey
时,它抛出
NotSupportedException

var store=new X509Store(StoreName.My,StoreLocation.CurrentUser);
打开(OpenFlags.ReadOnly);
证书=store1.证书;
var certificate=GetCertificateByThumbprint(证书,“51F9748FE7DDE895DD100AAD0BE54C1ACF6B4DCC”);
if(证书HasPrivateKey)
{
var kayalgorization==\u certificate.GetKeyAlgorithm();//与certificate.PublicKey.Oid.Value相同;
var rsaPrivateKey=certificate.GetRSAPrivateKey();
var dsaPrivateKey=_certificate.GetDSAPrivateKey();
var ecdsaPrivateKey=_certificate.GetECDsaPrivateKey();
var privateKey=certificate.privateKey;
}
hasprovatekey
返回true
GetRSAPrivateKey
GetDSAPrivateKey
GetECDsaPrivateKey
返回null。但是
GetKeyAlgorithm
(oid.value)返回“1.2.643.7.1.1.1.1”。我深入研究了
System.Security.Cryptography.X509Certificates.X509Certificate2
库,发现只对“1.2.840.113549.1.1”或“1.2.840.10040.4.1”算法进行了硬编码检查

public-gorithm-PrivateKey
{
得到
{
this.ThrowIfInvalid();
如果(!this.hasprovatekey)
返回(gorithm)null;
if(this._lazyprovatekey==null)
{
string keyAlgorithm=this.GetKeyAlgorithm();
如果(!(keyAlgorithm==“1.2.840.113549.1.1.1”))
{
如果(!(keyAlgorithm==“1.2.840.10040.4.1”))
抛出新的NotSupportedException(SR.NotSupported_-KeyAlgorithm);
this._lazyprovatekey=(非对称算法m)this.Pal.GetDSAPrivateKey();
}
其他的
this._lazyprovatekey=(非对称gorithm)this.Pal.getrsaprovatekey();
}
归还这个。_lazyprovatekey;
}
设置
{
抛出新平台NotSupportedException();
}
}
在.net framework中,获取
PrivateKey
会引发相同的异常<代码>系统.安全.加密.X509Certificates.X509Certificate2看起来与此不同

public-gorithm-PrivateKey
{
得到
{
如果(!this.hasprovatekey)
返回(gorithm)null;
if(this.m_privateKey==null)
{
CspParameters=新的CspParameters();
如果(!X509Certificate2.GetPrivateKeyInfo(this.m_safeCertContext,ref参数))
返回(gorithm)null;
parameters.Flags |=CSProviderFlags.UseExistingKey;
开关(this.PublicKey.AlgorithmId)
{
判例8704:
this.m_privateKey=(非对称算法m)新DSACryptoServiceProvider(参数);
打破
判例9216:
判例41984:
this.m_privateKey=(SymmetricGorithm)新的RSACryptServiceProvider(参数);
打破
违约:
抛出新的NotSupportedException(SR.GetString(“NotSupported_KeyAlgorithm”);
}
}
返回此.m_私钥;
}
设置
{
...
}
}
那么,我如何获得不同算法的
PrivateKey
,或者我以前是否犯过错误

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

private X509Certificate2 GetCertificateByThumbprint(X509Certificate2Collection Certificates,字符串指纹)
{
foreach(认证中的var证书)
{
if(certificate.Thumbprint==指纹)
退货证明;
}
}

由于.NET没有GOST的表示,因此PrivateKey属性无法返回任何有用的内容(如果它还没有被有效地弃用的话)


从X509Certificate2对象中,您可以读取
句柄
属性以获取底层OS值(Windows上的PCERT_上下文)。然后,您可以使用它将P/Invoke转换为操作系统函数,如。假设GOST CSP已在Windows中注册,该函数应成功返回CAPI或CNG密钥句柄(由dwKeySpec返回确定),然后您需要继续使用P/Invokes(可能通过您为管理它而创建的GOST类)。

您的CSP供应商(GOST)是否是否提供用于自定义应用程序的API库?检查它们是否为.NET类提供扩展。否则,您可能需要通过p/invoke使用CryptoAPI函数(legacy或CNG)来执行加密操作。请注意,这些可能不是跨平台的。也就是说,附带的API仅在Windows中可用。听起来您需要安装Crypto PRO中间件和相关软件才能访问密钥。@Crypt32,看起来Crypto PRO中间件为签名消息/数据/文件提供了类。然而,要创建这些类,我需要证书和它的私钥。crypto pro网站上的示例中没有特殊的扩展方法或类似的东西。只需certificate.PrivateKey。您应该仔细查阅Crypto Pro文档。您是否尝试在.NETFramework项目中运行示例?可能有这样的情况,Crypto Pro与.NET Core不兼容。@Crypt32,是的,我创建了.NET framework控制台应用程序,它会抛出相同的错误
System.Security.Cryptography.X509Certificates.X509Certificate2
与.net核心稍有不同。我已经在原来的帖子中添加了源代码。似乎它也在检查oid。只是另一种方式。