【问题标题】:'Cannot find the requested object' exception while creating X509Certificate2 from string从字符串创建 X509Certificate2 时出现“找不到请求的对象”异常
【发布时间】:2017-10-18 14:28:00
【问题描述】:

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

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

而keyBase64String有这样一个内容:"MIIF0QYJKoZI ........hvcNAQcCoIIFwjCCBb4CA0="

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

创建X509Certificate2时出现以下异常:

找不到请求的对象

还有堆栈跟踪:

“找不到请求的对象”X509Certificate2 异常“找不到 请求的对象”} 在 System.Security.Cryptography.CryptographicException.ThrowCryptographicException(Int32 小时)在 System.Security.Cryptography.X509Certificates.X509Utils._QueryCertBlobType(字节[] 原始数据)在 System.Security.Cryptography.X509Certificates.X509Certificate.LoadCertificateFromBlob(字节[] rawData,对象密码,X509KeyStorageFlags keyStorageFlags)在 System.Security.Cryptography.X509Certificates.X509Certificate2..ctor(字节 [] 原始数据)在 WebApp.SoupController.d__7.MoveNext() 在 D:\Projects\WebApp\Controllers\SoupController.cs:line 118

请告诉我我做错了什么。任何帮助将不胜感激!

【问题讨论】:

  • 您尝试使用构造函数加载的数据实际上是 PKCS7 格式吗?您的命名表明
  • @mat 它是一个证书,但它存储为字节数组。
  • 普通的 X.509 证书?那你为什么叫它PKCS7呢?

标签: c# encryption public-key-encryption x509certificate2


【解决方案1】:

如果 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,您可能需要集合导入(实例)方法。如果不是,您有一些奇怪的变量/字段/属性名称。

【讨论】:

    【解决方案2】:

    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];
    

    您也可以尝试FindByKeyUsage、FindBySubjectKeyIdentifier或其他类型的X509FindType Enumeration

    【讨论】:

    • 我有一个例外Index was out of range. Must be non-negative and less than the size of the collection. Parameter name: index。也许我们应该将证书放入X509Store?
    • 是的,您需要将证书添加到您尝试使用 Find 方法访问的证书存储中,如答案中所述。如果没有找到证书,则返回的集合为空,因此发生异常。
    • @MichaelBeck 如何将证书添加到证书存储?我只是从 SQL Server 下载。
    • X509Certificate2 有一个构造函数,它接收一个字节数组(代表证书)作为参数,请参阅 MSDN X509Certificate 2 Constructor - 之后您可以将证书添加到存储中(请参阅@987654324 @) 如果这是你需要的;但您也可以直接使用证书,具体取决于您的要求。
    猜你喜欢
    • 2016-11-18
    • 2012-02-26
    • 1970-01-01
    • 2011-07-01
    • 2017-07-20
    • 2015-03-20
    • 2011-10-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多