首页 > 解决方案 > 使用 C# 将证书从 LocalComputer 复制到 CurrentUser

问题描述

正如标题所说,我需要以编程方式将证书(给定指纹)从 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);

我觉得我在这里有点走在正确的轨道上,但非常感谢任何帮助:)

标签: c#.netwindowsx509certificate

解决方案


  • 无需将其保存到文件中,因为您可以byte[]直接从文件中加载 PFX。
  • 您似乎没有调用currentUserStore.Open(OpenFlags.ReadWrite),代码是完成还是抛出 CryptographicException?
  • 您需要导入 PFX,X509KeyStorageFlags.UserKeySet因为私钥会“记住”它是从机器密钥库导出的,并且它想回到那里。
  • 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();

推荐阅读