【问题标题】:Private key is null when accessing via code, why?通过代码访问时私钥为空,为什么?
【发布时间】:2013-01-23 03:48:34
【问题描述】:

我的机器上安装了一个证书,当我去查看它时,我看到消息“您有一个与此证书对应的私钥”但是,当我尝试在代码中访问该私钥时,它是空值。我使用以下代码来获取我的证书:

var x509Certificate = GetCertificate(StoreName.My, StoreLocation.LocalMachine, "CN=SomeCert");

地点:

public X509Certificate2 GetCertificate(string storeName, string storeLocation, string subjectName)
{
     var store = new X509Store(getStoreName(storeName), getStoreLocation(storeLocation));
     X509Certificate2Collection certificates = null;
     store.Open(OpenFlags.ReadOnly);

     try
     {
          X509Certificate2 result = null;
          certificates = store.Certificates;
          return getCertificateResult(certificates, subjectName, result);
     }
     finally
     {
          if (certificates != null)
          {
               foreach (var cert in certificates)
               {
                    cert.Reset();
               }
          }
          store.Close();
     }
}

还有:

private static X509Certificate2 getCertificateResult(IEnumerable certificates, string subjectName, X509Certificate2 result)
{
     foreach (var cert in certificates.Cast<X509Certificate2>().Where(cert => cert.SubjectName.Name != null && cert.SubjectName.Name.ToLower() == subjectName.ToLower()))
     {
          if (result != null)
          {
             throw new ApplicationException(string.Format("There is more than one certificate found for subject Name {0}", subjectName));
          }
          result = new X509Certificate2(cert);
     }

     if (result == null)
     {
          throw new ApplicationException(string.Format("No certificate was found for subject Name {0}", subjectName));
     }
     return result;
}

我可以很好地取回我的证书,但是当我尝试访问私钥时,请执行以下操作:

x509Certificate.PrivateKey

PrivateKey 的值为空。我究竟做错了什么?我需要这个值来签署 SAML2 请求。

注意:我知道我在其中有一些抽象,但重点是我取回了证书(已找到)但私钥为空。如果有任何关于我的抽象的更多信息导致问题无法回答,我可以提供更多细节。

【问题讨论】:

  • 您的应用程序是否在您的登录用户下运行?可能是权限问题?虽然我认为这会引发异常,而不仅仅是给出一个空值。
  • 在“管理私钥”下,运行应用程序池的用户列出了完全控制权。是这个意思吗?
  • 你确定你周围没有任何例外吗?
  • 没有抛出异常,只是一个 null PrivateKey

标签: c# asp.net certificate x509certificate x509certificate2


【解决方案1】:

我知道这个问题已经很老了,但对于任何未来的读者,让我补充一下我的想法。

在我看来,您获得的证书似乎不包含私钥。商店中的所有证书都没有私钥。当然,您自己的证书将具有私钥,但其他实体的证书将没有私钥,这是有意义的。

在您的代码中,您没有显示您从中获取证书的商店位置。难道你拿到的证书不是你自己的?

【讨论】:

    【解决方案2】:

    重置的documentation 声明它释放了证书的资源。当然,由于该方法称为 Reset 而不是 Dispose,因此可以合理地假设实例应该能够在以后再次需要这些资源时重新获取这些资源。不幸的是,事实并非如此。

    在 GetCertificate 的 finally 块中,您对集合中的每个证书(包括您要返回的证书)调用 Reset,这使其无用。

    【讨论】:

    • 显然不是这样。在 getCertificateResult 方法中,他显然是在创建一个新的证书实例并返回它。所以它会在返回时有正确的细节。
    【解决方案3】:

    正如它所描述的here.cer 文件(我猜它也适用于所有证书格式)不能包含私钥。从安全的角度来看,它看起来是正确的,因为这个文件是公开的。
    但是X509Certificate2 不仅仅是一个证书,它是证书本身和其他一些东西的容器。这就是为什么它有属性PrivateKey。如果您在代码中需要此信息并且您有私钥文件 (.pvk) 和密码 - 您可以使用 .pfx 文件而不是 .cer。它可以使用pvk2pfx 实用程序创建:

    > MakeCert -r -pe -ss SampleStoreName -n "CN=Sample" Sample.cer -sky exchange -sv Sample.pvk
    > pvk2pfx -pvk Sample.pvk -pi SamplePassword -spc Sample.cer -pfx Sample.pfx -f
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-01-21
      • 1970-01-01
      • 2010-11-17
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多