使用C#将证书从LocalComputer复制到CurrentUser

时间:2018-06-29 04:23:56

标签: c# .net windows x509certificate

正如标题所述,我需要以编程方式将证书(赋予指纹)从LocalComputer存储复制到CurrentUser存储。我一直在研究X509Certificate2定义并尝试一些东西,但似乎没有任何效果。这是我到目前为止所拥有的

certPath = "@"C:\%temp%\Cert.pfx";
certPass = "CertPassHere";    

X509Store localMachineStore = new X509Store(StoreName.My, StoreLocation.LocalMachine);
localMachineStore.Open(OpenFlags.ReadOnly);

X509Certificate2Collection certificate = localMachineStore.Certificates.Find(X509FindType.FindByThumbprint, "certThumbprint", true);
byte[] rawCertData = certificate[0].Export(X509ContentType.Pfx, certPass);
File.WriteAllBytes(certPath, rawCertData);
localMachineStore.Close();

X509Certificate2Collection collection = new X509Certificate2Collection();
collection.Import(certPath, certPass, X509KeyStorageFlags.PersistKeySet);
X509Store currentUserStore = new X509Store(StoreName.My, StoreLocation.CurrentUser);

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

currentUserStore.Close();
File.Delete(certPath);

我觉得我在这里步入正轨,但是非常感谢您的帮助:)

1 个答案:

答案 0 :(得分:1)

  • 无需将其保存到文件中,因为您可以直接从byte[]加载PFX。
  • 您似乎没有致电currentUserStore.Open(OpenFlags.ReadWrite),代码是否已完成,或者引发了CryptographicException?
  • 您需要使用X509KeyStorageFlags.UserKeySet导入PFX,因为私钥会“记住”它是从机器密钥库中导出的,并且它想回到那里。
  • true作为第三个参数传递给X509Certificate2Collection.Find通常不是您想要的,它仅在按主题搜索时才有用,可以忽略过期的内容。

string thumbprint = IAssumeYouHaveThisForReal();

X509Certificate2Collection certificates = localMachineStore.Certificates.Find(
    X509FindType.FindByThumbprint,
    thumbprint,
    false);

byte[] tempPfx = certificates[0].Export(X509ContentType.Pfx, "hi");

X509Certificate2 copyWithUserKey = new X509Certificate2(
    tempPfx,
    "hi",
    X509KeyStorageFlags.UserKeySet /*| X509KeyStorageFlags.Exportable if you like */);

X509Store currentUserMy = new X509Store(StoreName.My, StoreLocation.CurrentUser);
currentUserMy.Open(OpenFlags.ReadWrite);
currentUserStore.Add(copyWithUserKey);

certificates = currentUserStore.Certificates.Find(
    X509FindType.FindByThumbprint,
    thumbprint,
    false);

if (certificates.Count != 1)
    throw new InvalidOperationException();