如何使用私钥安装 .cer 文件并导出到 .pfx 文件

How to Install a .cer file and Export to a .pfx file with private key

我的客户要求我安装没有私钥的 .cer 文件,然后使用 C# 将其导出到带有私钥的 .pfx 文件

我尝试了所有提供的不同解决方案,这些解决方案允许我将 .cer 导出到 .pfx 但没有密钥并且 .pfx 文件为空

string file = @"C:\TestCert1.cer";
X509Store store = new X509Store(StoreName.My, StoreLocation.CurrentUser);
store.Open(OpenFlags.ReadWrite);
X509Certificate2 test = new X509Certificate2(X509Certificate2.CreateFromCertFile(file));
string name = test.SerialNumber;
store.Certificates.Insert(0, test);
store.Add(test);
store.Close();

byte[] certData = store.Certificates.Export(X509ContentType.Pfx, "MyPassword");
File.WriteAllBytes(@"C:\MyCert.pfx", certData);

这部分还可以:

string file = @"C:\TestCert1.cer";
X509Store store = new X509Store(StoreName.My, StoreLocation.CurrentUser);
store.Open(OpenFlags.ReadWrite);

而不是

X509Certificate2 test = new X509Certificate2(X509Certificate2.CreateFromCertFile(file));

你想要更简单的

X509Certificate2 test = new X509Certificate2(file);

不确定这是干什么用的,您从未使用过该变量。

string name = test.SerialNumber;

这一行没有任何用处。 (store.Certificates returns 一个新集合,它是当时商店状态的副本......您添加到该集合然后让它超出范围)。

store.Certificates.Insert(0, test);

这个实际上是将证书添加到商店中,所以没关系,但对于您的目标来说不是必需的。

store.Add(test);

所以现在您关闭商店然后尝试将其导出。这没有意义,已关闭商店的 Certificates 属性 总是 returns 一个空集合。 (本来应该扔的,可是那艘船早就开航了)

store.Close();

byte[] certData = store.Certificates.Export(X509ContentType.Pfx, "MyPassword");
File.WriteAllBytes(@"C:\MyCert.pfx", certData);

您可能想要的是打开文件,然后浏览商店并查看是否有匹配项,然后导出匹配项。

using (X509Certificate2 filter = new X509Certificate2(file))
using (X509Store store = new X509Store(StoreName.My, StoreLocation.CurrentUser))
{
    store.Open(OpenFlags.ReadOnly);

    // The bytes making up the certificate, in DER/binary form.
    byte[] filterRawData = filter.RawData;

    foreach (X509Certificate2 storeCert in store.Certificates)
    {
        if (storeCert.RawData.SequenceEquals(filterRawData))
        {
            File.WriteAllBytes(outputFileName, storeCert.Export(X509ContentType.Pfx, password));
            return;
        }
    }   
}

Console.WriteLine("No match found...");