c# – 如何从PKCS#12字节数组构造X509Certificate2抛出CryptographicException(“系统找不到指定的文件。”)?

我试图从字节数组中的PKCS#12 blob构造一个X509Certificate2,并得到一个令人困惑的错误。此代码在Windows XP上具有管理员权限的桌面应用程序中运行。

堆栈跟踪如下,但我失去了尝试排除故障,因为_LoadCertFromBlob标记[MethodImpl(MethodImplOptions.InternalCall)]。

System.Security.Cryptography.CryptographicException: The system cannot find the file specified.
  at System.Security.Cryptography.CryptographicException.ThrowCryptogaphicException(Int32 hr)
  at System.Security.Cryptography.X509Certificates.X509Utils._LoadCertFromBlob(Byte[] rawData, IntPtr password, UInt32 dwFlags, Boolean persistKeySet, SafeCertContextHandle& pCertCtx)
  at System.Security.Cryptography.X509Certificates.X509Certificate.LoadCertificateFromBlob(Byte[] rawData, Object password, X509KeyStorageFlags keyStorageFlags)
  at System.Security.Cryptography.X509Certificates.X509Certificate2..ctor(Byte[] rawData, String password, X509KeyStorageFlags keyStorageFlags)

编辑:blob是由BouncyCastle for C#生成的一个真正的PKCS#12包含RSA私钥和证书(自签名或最近注册与CA) – 我想做的是将私钥和证书从BouncyCastle库导出到System.Security.Cryptography库,并从一个导出到另一个。这个代码适用于绝大多数已经尝试过的系统;我从来没有看到从该构造函数抛出的特定错误。它可能是某种环境奇怪在那一个盒子。

编辑2:错误发生在不同的城市中的不同的环境,我无法在本地重现,所以我可能最终不得不粉碎它一个破碎的XP安装。

因为你问,虽然,这里是有问题的片段。代码采用BouncyCastle表示中的私钥和证书,从个人密钥存储中删除相同可分辨名称的任何先前证书,并通过中间PKCS#12 blob将新的私钥和证书导入到个人密钥存储中。

// open the personal keystore
var msMyStore = new X509Store(StoreName.My);
msMyStore.Open(OpenFlags.MaxAllowed);

// remove any certs previously issued for the same DN
var oldCerts =
    msMyStore.Certificates.Cast<X509Certificate2>()
        .Where(c => X509Name
                        .GetInstance(Asn1Object.FromByteArray(c.SubjectName.RawData))
                        .Equivalent(CurrentCertificate.SubjectDN))
        .ToArray();
if (oldCerts.Length > 0) msMyStore.RemoveRange(new X509Certificate2Collection(oldCerts));

// build a PKCS#12 blob from the private key and certificate
var pkcs12store = new Pkcs12StoreBuilder().Build();
pkcs12store.SetKeyEntry(_Pkcs12KeyName,
                        new AsymmetricKeyEntry(KeyPair.Private),
                        new[] {new X509CertificateEntry(CurrentCertificate)});
var pkcs12data = new MemoryStream();
pkcs12store.Save(pkcs12data, _Pkcs12Password.ToCharArray(), Random);

// and import it.  this constructor call blows up
_MyCertificate2 = new X509Certificate2(pkcs12data.ToArray(),
                                       _Pkcs12Password,
                                       X509KeyStorageFlags.Exportable);
msMyStore.Add(_MyCertificate2);
msMyStore.Close();
你有PKCS#12或只是PFX文件?在微软的世界里是一样的,但其他人认为另一个(见http://www.drh-consultancy.demon.co.uk/pkcs12faq-old.html#PFX)。

你可以试试看下面

X509Certificate2 cert = X509Certificate2(byte[] rawData, "password");
X509Certificate2 cert2 = X509Certificate2(byte[] rawData, "password",
              X509KeyStorageFlags.MachineKeySet |
              X509KeyStorageFlags.PersistKeySet |
              X509KeyStorageFlags.Exportable);

(见http://msdn.microsoft.com/en-us/library/ms148418.aspx)或

X509Certificate2 cert = X509Certificate2("C:\Path\my.pfx", "password");

(如果需要使用一些标志,请参见http://msdn.microsoft.com/en-us/library/ms148420.aspxhttp://msdn.microsoft.com/en-us/library/ms148442.aspx)

UPDATED:如果你插入一个代码片段而不仅仅是异常堆栈跟踪将是有帮助的。

你使用哪个X509KeyStorageFlags?您可以使用Process Monitor找出哪个文件找不到X509Certificate2构造函数。例如,可以在具有该问题的Windows XP上没有用于当前用户的默认密钥容器。您可以创建它并重试导入。

http://stackoverflow.com/questions/3826321/how-can-constructing-an-x509certificate2-from-a-pkcs12-byte-array-throw-cryptog

本站文章除注明转载外,均为本站原创或编译
转载请明显位置注明出处:c# – 如何从PKCS#12字节数组构造X509Certificate2抛出CryptographicException(“系统找不到指定的文件。”)?