C# 如何将多个.p12证书合并到一个.pfx文件中

C# 如何将多个.p12证书合并到一个.pfx文件中,c#,certificate,x509certificate2,C#,Certificate,X509certificate2,我有大量单个证书存储为扩展名为.p12的文件。我希望将所有这些证书合并到一个.pfx文件中,以减少在客户端机器上导入所有这些证书的工作量。 这是我试过的。它创建了文件,但在导入.pfx文件时出现了问题。Windows证书导入向导仅导入第一个证书,并忽略其后的所有内容。我假设是因为文件的格式有问题,所以我尝试合并它们。我不确定这样做的正确方法。有什么想法吗 private void btnCombineCerts_Click(object sender, EventArgs e) { St

我有大量单个证书存储为扩展名为.p12的文件。我希望将所有这些证书合并到一个.pfx文件中,以减少在客户端机器上导入所有这些证书的工作量。 这是我试过的。它创建了文件,但在导入.pfx文件时出现了问题。Windows证书导入向导仅导入第一个证书,并忽略其后的所有内容。我假设是因为文件的格式有问题,所以我尝试合并它们。我不确定这样做的正确方法。有什么想法吗

private void btnCombineCerts_Click(object sender, EventArgs e)
{
    String dateString = DateTime.Now.ToString("yyyyMMdd");
    String timeString = DateTime.Now.ToString("hhmmssff");
    String path = Directory.GetCurrentDirectory() + @"\certs\CombinedCerts\";
    if (!Directory.Exists(path))
    {
        Directory.CreateDirectory(path);
    }
    List<X509Certificate2> certs = new List<X509Certificate2>();
    foreach(var certFile in fDialog.FileNames)
    {
        X509Certificate2 cert = new X509Certificate2(certFile);
        certs.Add(cert);
    }
    foreach(X509Certificate2 cert in certs)
    {                
        byte[] certStream = cert.Export(X509ContentType.Pfx);
        using (var stream = new FileStream(path + dateString + "CombinedCerts" + timeString + ".pfx", FileMode.Append))
        {
            stream.Write(certStream, 0, certStream.Length);
        }

    }
}
private void btnCombineCerts\u单击(对象发送方,事件参数e)
{
String dateString=DateTime.Now.ToString(“yyyyMMdd”);
String timeString=DateTime.Now.ToString(“hhmmsff”);
字符串路径=Directory.GetCurrentDirectory()++“\certs\CombinedCerts\”;
如果(!Directory.Exists(path))
{
CreateDirectory(路径);
}
列表证书=新列表();
foreach(fDialog.FileNames中的var certFile)
{
X509Certificate2证书=新的X509Certificate2(证书文件);
证书。添加(证书);
}
foreach(X509Certificate2证书中的证书)
{                
字节[]certStream=cert.Export(X509ContentType.Pfx);
使用(var stream=newfilestream(path+dateString+“CombinedCerts”+timeString+“.pfx”,FileMode.Append))
{
Write(certStream,0,certStream.Length);
}
}
}

PFX固有地支持多个证书,但它不像您编写的那样是一个顺序文件。我不知道UI是否能正确导入,但如果所有东西都有私钥,它可能会正确导入。X509Certificate2Collection的一个真正用途是它可以导出或导入

var certs = new X509Certificate2Collection();

foreach (var certFile in fDialog.FileNames)
{
    certs.Add(new X509Certificate2(certFile));
}

byte[] oneBigPfx = certs.Export(X509ContentType.Pfx);
File.WriteAllBytes(filename, oneBigPfx);
public X509Certificate2合并(列出证书)
{
var certs=new X509Certificate2Collection();
foreach(证书中的var certFile)
{
证书添加(新的X509Certificate2(证书文件));
}
字节[]数据=证书导出(X509ContentType.Pfx);
X509Certificate2 newFile=新X509Certificate2(数据);
返回新文件;
}

这项功能非常有效。非常感谢。我还将提到导出方法需要一个密码参数,这是一个额外的好处。在我的例子中,为两个证书运行上述代码时,我得到了(德语)错误消息
System.Security.Cryptography.cryptographyException:Schlüssel ist im angegebenen Status nicht gültig。
。翻译后,此项显示
密钥在指定状态下无效。
。看来你避免了这个错误。即使对于没有密码的证书也有效;只需指定一个空字符串即可。
public X509Certificate2 Merge(List<X509Certificate2> certificates)
{
    var certs = new X509Certificate2Collection();

    foreach (var certFile in certificates)
    {
        certs.Add(new X509Certificate2(certFile));
    }

    byte[] data = certs.Export(X509ContentType.Pfx);

    X509Certificate2 newFile = new X509Certificate2(data);

    return newFile;
}