【问题标题】:X509 certificate imported from certificate store has no private key从证书存储导入的 X509 证书没有私钥
【发布时间】:2019-12-06 15:47:01
【问题描述】:

有一些简单的代码可以使用 .net core 2.2 将带有私钥的证书导入 Windows 证书存储区:

  using (var store = new X509Store(StoreName.Root,StoreLocation.CurrentUser))
  {
      store.Open(OpenFlags.ReadWrite);
      store.Add(cert);
      store.Close();
  }

还有一些简单的代码可以再次读取它:

 using (var store = new X509Store(StoreName.Root,StoreLocation.CurrentUser))
 {
    store.Open(OpenFlags.ReadOnly);
    var certCollection = store.Certificates.Find(X509FindType.FindBySubjectName, commonName, validOnly);
    store.Close();
    return certCollection;
 }

但是,尽管证书已成功检索到 certCollection,但它的私钥为 null 且 hasPrivateKey 为 false,即使它们在之前的 Add 调用中不为 null 且为 true。这是为什么呢?

更新:

using (RSA rsa = RSA.Create(keySize)) {    
     CertificateRequest certRequest = new CertificateRequest(
         subjectName,
         rsa,
         HashAlgorithmName.SHA512,
         RSASignaturePadding.Pkcs1);

     certRequest.CertificateExtensions
         .Add(newX509SubjectKeyIdentifierExtension(certRequest.PublicKey, false));  
     return certRequest;
}

【问题讨论】:

  • Windows 不希望根存储中的证书具有关联的私钥(如果有,则将有一个副本知道我的存储中的私钥)。有可能 Windows 只是在将相关的密钥知识保存到存储中时将其擦除。
  • 很高兴看到第一个示例中cert 的来源。
  • @Crypt32 Cert 只是内存中的 X509Certificate2;使用 C# 创建。
  • “使用 C# 创建” - 如何创建?从带有 EphemeralKeySet 标志的 PFX 打开?使用证书请求? (如果是后者,您可能没有创建持久密钥,并且临时密钥不会在存储添加中持久)

标签: c# .net-core certificate x509certificate2


【解决方案1】:

您的密钥被创建为临时密钥,因此当它被添加到持久存储时,密钥将被丢弃。

如果要将密钥持久化到存储证书中,则需要直接将其创建为持久化密钥,或者导出到 PFX 然后重新导入(这是最简单的形式):

// If you're planning on saving to a LocalMachine store you should also | in the
// X509KeyStorageFlags.MachineKeySet bit.
X509KeyStorageFlags storageFlags = X509KeyStorageFlags.PersistKeySet;

X509Certificate2 certWithPersistedKey =
    new X509Certificate2(
        certWithEphemeralKey.Export(X509ContentType.Pkcs12, ""),
        "",
        storageFlags);

现在certWithPersistedKey 可以像您期望的那样添加。

【讨论】:

  • 酷,我特别希望你在我问的时候能看到我的问题,因为我读了一堆你的其他 SO 答案和 github 的好东西,这一切都很棒。那谢谢啦。这似乎也解决了我使用根 CA 证书创建中间 CA 证书的次要问题。当我尝试与中介签署最终实体证书时,他们会说根 CA 没有密钥 - 那里需要更多测试,但到目前为止还不错。
  • 实际上对于我的第二个问题,我也需要certificate.CopyWithPrivateKey(rsa);,因为使用 issuerCertificate 的创建方法不会像创建自签名证书时那样执行此操作。可以在这里找到关于 CopyWithPrivateKey 工作原理的精彩讨论:github.com/dotnet/corefx/issues/19888
猜你喜欢
  • 2011-11-09
  • 1970-01-01
  • 2012-10-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-02-17
  • 1970-01-01
相关资源
最近更新 更多