从字符串创建X509Certificate2时出现“找不到请求的对象”异常

25

我正在尝试从字符串创建X509Certificate2。让我举个例子:

string keyBase64String = Convert.ToBase64String(file.PKCS7);
var cert = new X509Certificate2(Convert.FromBase64String(keyBase64String));

keyBase64String具有如下内容:"MIIF0QYJKoZI ........hvcNAQcCoIIFwjCCBb4CA0="

file.PKCS7我从数据库中下载的字节数组

在创建X509Certificate2时,我遇到了以下异常:

找不到请求的对象

以下是堆栈跟踪:

"Cannot find requested object" X509Certificate2 Exception "Cannot find requested object"} at System.Security.Cryptography.CryptographicException.ThrowCryptographicException(Int32 hr) at System.Security.Cryptography.X509Certificates.X509Utils._QueryCertBlobType(Byte[] rawData) at System.Security.Cryptography.X509Certificates.X509Certificate.LoadCertificateFromBlob(Byte[] rawData, Object password, X509KeyStorageFlags keyStorageFlags) at System.Security.Cryptography.X509Certificates.X509Certificate2..ctor(Byte[] rawData) at WebApp.SoupController.d__7.MoveNext() in D:\Projects\WebApp\Controllers\SoupController.cs:line 118

请告诉我我的错误在哪里。任何帮助都将不胜感激!


你正在尝试使用构造函数加载的数据是否实际上是PKCS7格式?你的命名方式表明了这一点。 - mat
@mat 这是一个证书,但它以字节数组的形式存储。 - StepUp
1
一个普通的X.509证书?那你为什么叫它PKCS7呢? - mat
2个回答

5
如果file.PKCS7表示PKCS#7 SignedData blob(从X509Certificate2.Export(X509ContentType.Pkcs7)X509Certificate2Collection.Export(X509ContentType.Pkcs7)生成),则有两种不同的打开方法:
  • new X509Certificate2(byte[])/new X509Certificate2(string)
    • 单个证书构造函数将提取SignedData blob的签名证书。如果这只是作为证书集合导出,但没有签署任何内容,则不存在此类证书,因此会出现错误Cannot find the original signer.(Win 2012r2,其他版本可能将其映射到不同的字符串)
  • X509Certificate2Collection::Import(byte[])/X509Certificate2Collection::Import(string)
    • 集合导入将使用所有“额外”证书,忽略签名证书。

因此,如果它确实是PKCS#7,则可能需要使用集合导入(instance)方法。如果不是,则您可能具有一些奇怪的变量/字段/属性名称。


-1

X509Certificate2的构造函数需要传入证书文件名,但您提供了一个密钥(X509Certificate2 Constructor (String))

我假设keyBase64String是证书密钥,并且该证书已安装在执行代码的计算机上。请尝试以下操作:

var store = new X509Store(StoreName.My, StoreLocation.LocalMachine);
store.Open(OpenFlags.ReadOnly);
var certCollection = store.Certificates.Find(X509FindType.FindByThumbprint, keyBase64String , false);
var cert = certCollection[0];

您还可以尝试使用FindByKeyUsageFindBySubjectKeyIdentifier或其他X509FindType枚举类型

1
我遇到了一个异常:“索引超出范围。必须是非负数且小于集合大小的值。参数名:index”。也许我们应该将证书放入“X509Store”中? - StepUp
是的,正如答案中所述,您需要将证书添加到您尝试使用Find方法访问的证书存储中。如果未找到该证书,则返回的集合为空,因此会出现异常。 - Michael Beck
@MichaelBeck 我该如何将证书添加到证书存储中?我只是从 SQL Server 下载。 - StepUp
4
X509Certificate2有一个构造函数,它接收一个字节数组(代表证书)作为参数,请参见MSDNX509Certificate2 构造函数 - 之后您可以将证书添加到存储区(请参见X509Store.Add),如果需要的话; 但根据您的要求,您也可以直接使用证书。 - Michael Beck

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接