如何以编程方式将带有证书链的pfx导入证书存储区?

Edw*_*ing 21 c# pfx pkcs#12 x509certificate2

我正在尝试以编程方式在我的本地计算机的证书存储中导入X509证书(pfx/PKCS#12).此特定证书具有一系列证书,证书路径如下所示:

  • 根证书CA.
    • 组织证书CA.
      • 组织2证书CA.
        • 我的证书

我使用的代码如下所示:

cert = new X509Certificate2(pathToCert, password);

if (cert != null)
{
    var store = new X509Store(StoreName.My, StoreLocation.LocalMachine);
    store.Open(OpenFlags.ReadWrite);
    if (!store.Certificates.Contains(cert))
    {
        store.Add(cert);
    }
}
Run Code Online (Sandbox Code Playgroud)

此代码确实导入了证书,但它似乎忽略了链.如果我检查商店中的证书,则证书路径仅显示:

  • 我的证书

但是,当我手动导入pfx时,它确实显示完整路径.我在这里跳过一步,还是我错过了一些参数?有人可以对此有所了解吗?

Bil*_*gee 16

您应该能够通过打开PFX文件作为X509Certificate2Collection对象来迭代PFX中的证书(并将每个证书导入到您选择的证书库中).

以下是X509Certificate2Collection上的文档:

http://msdn.microsoft.com/en-us/library/system.security.cryptography.x509certificates.x509certificate2collection.aspx

MSDN在该文档页面中提供了一些示例代码,介绍如何检查集合中的每个证书.

一旦您知道有关每个证书的CN /发布者/其他信息,就应该清楚每个证书库需要添加到哪个证书库.为此,您可以使用X509Store类和StoreName枚举来指定要打开/添加的商店:

http://msdn.microsoft.com/en-us/library/system.security.cryptography.x509certificates.x509store.aspx

http://msdn.microsoft.com/en-us/library/system.security.cryptography.x509certificates.storename.aspx

另请参阅我对类似SO问题的回答:

如何使用c#从pfx文件中检索证书?

正如在该答案的最新评论之一中所提到的,当您尝试将证书导入当前用户的根存储("StoreName.Root"和"StoreLocation.CurrentUser"作为名称/位置)时,您将看到一个弹出对话框询问你确认一下.

为了解决这个问题,我刚刚在我的证书导入方法中添加了一些MS UI自动化代码,在提示符上单击"确定".

或者,正如评论者"CodeWarrior"在另一个SO答案的注释中所说,为了避免弹出对话框,您可以尝试将根证书放入LocalMachine商店而不是CurrentUser.

示例代码:

string certPath = <YOUR PFX FILE PATH>;
string certPass = <YOUR PASSWORD>;

// Create a collection object and populate it using the PFX file
X509Certificate2Collection collection = new X509Certificate2Collection();
collection.Import(certPath, certPass, X509KeyStorageFlags.PersistKeySet);

foreach (X509Certificate2 cert in collection)
{
    Console.WriteLine("Subject is: '{0}'", cert.Subject);
    Console.WriteLine("Issuer is:  '{0}'", cert.Issuer);

    // Import the certificate into an X509Store object
}
Run Code Online (Sandbox Code Playgroud)

  • 这在我的情况下不起作用,导入集合后仅包含一个证书(我的证书)。我想你还是有所收获的。 (2认同)
  • 仅供参考,对于在 Powershell 中使用它而没有编译错误的任何人,X509Certificate2Collection.Import 没有像 X509Certificate2.Import 方法那样的 SecureString 重载。 (2认同)

Edw*_*ing 8

为了将来参考,我发现了另一种使用X509Chain对象的方法:

var cert = new X509Certificate2(pathToCert, password);

X509Chain chain = new X509Chain();
chain.Build(cert);
for (int i = 0; i < chain.ChainElements.Count; i++)
{
   //add to the appropriate store
}
Run Code Online (Sandbox Code Playgroud)

  • 您是否有机会共享“到适当的商店”代码以使其成为通用解决方案? (2认同)