title: How to give ASP.NET access to a private key in a certificate in the certificate store?
body: <p>I have an ASP.NET application that accesses private key in a certificate in the certificates store. On Windows Server 2003 I was able to use winhttpcertcfg.exe to give private key access to the NETWORK SERVICE account. How do I give permissions to access a Private Key in a certificate in the certificate store (Local Computer\Personal) on a Windows Server 2008 R2 in an IIS 7.5 website?</p>
  
  <p>I've tried giving Full Trust access to "Everyone", "IIS AppPool\DefaultAppPool", "IIS_IUSRS", and everyother security account I could find using the Certificates MMC (Server 2008 R2). However the below code demonstrates that the code does not have access to the Private Key of a certificate that was imported with the private key. The code instead throws and error everytime the private key property is accessed.</p>
  
  <p><strong>Default.aspx</strong>
  <code><pre>&lt;%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" %&gt;
  &lt;%@ Import Namespace="System.Security.Cryptography.X509Certificates" %&gt;
  &lt;!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "<a href="http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd" rel="noreferrer">http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd</a>"&gt;
  &lt;html xmlns="http://www.w3.org/1999/xhtml"&gt;
  &lt;head runat="server"&gt;
      &lt;title&gt;&lt;/title&gt;
  &lt;/head&gt;
  &lt;body&gt;
      &lt;form id="form1" runat="server"&gt;
      &lt;div&gt;
          &lt;asp:Repeater ID="repeater1" runat="server"&gt;
              &lt;HeaderTemplate&gt;
                  &lt;table&gt;
                      &lt;tr&gt;
                          &lt;td&gt;
                              Cert
                          &lt;/td&gt;
                          &lt;td&gt;
                              Public Key
                          &lt;/td&gt;
                          &lt;td&gt;
                              Private Key
                          &lt;/td&gt;
                      &lt;/tr&gt;
              &lt;/HeaderTemplate&gt;
              &lt;ItemTemplate&gt;
                  &lt;tr&gt;
                      &lt;td&gt;
                      &lt;%#((X509Certificate2)Container.DataItem).GetNameInfo(X509NameType.SimpleName, false) %&gt;
                      &lt;/td&gt;
                      &lt;td&gt;
                      &lt;%#((X509Certificate2)Container.DataItem).HasPublicKeyAccess() %&gt;
                      &lt;/td&gt;
                      &lt;td&gt;
                      &lt;%#((X509Certificate2)Container.DataItem).HasPrivateKeyAccess() %&gt;
                      &lt;/td&gt;
                  &lt;/tr&gt;
              &lt;/ItemTemplate&gt;
              &lt;FooterTemplate&gt;
                  &lt;/table&gt;&lt;/FooterTemplate&gt;
          &lt;/asp:Repeater&gt;
      &lt;/div&gt;
      &lt;/form&gt;
  &lt;/body&gt;
  &lt;/html&gt;</pre></code></p>
  
  <p><strong>Default.aspx.cs</strong>
  <code><pre>
  using System;
  using System.Security.Cryptography;
  using System.Security.Cryptography.X509Certificates;
  using System.Web.UI;
  public partial class _Default : Page 
  {
      public X509Certificate2Collection Certificates;
      protected void Page_Load(object sender, EventArgs e)
      {
          // Local Computer\Personal
          var store = new X509Store(StoreLocation.LocalMachine);
          // create and open store for read-only access
          store.Open(OpenFlags.ReadOnly);
          Certificates = store.Certificates;
          repeater1.DataSource = Certificates;
          repeater1.DataBind();
      }
  }
  public static class Extensions
  {
      public static string HasPublicKeyAccess(this X509Certificate2 cert)
      {
          try
          {
              AsymmetricAlgorithm algorithm = cert.PublicKey.Key;
          }
          catch (Exception ex)
          {
              return "No";
          }
          return "Yes";
      }
      public static string HasPrivateKeyAccess(this X509Certificate2 cert)
      {
          try
          {
              string algorithm = cert.PrivateKey.KeyExchangeAlgorithm;
          }
          catch (Exception ex)
          {
              return "No";
          }
          return "Yes";
      }
  }</pre>
  </code></p>