如何让ASP.NET访问证书存储区中的证书中的私钥?

tha*_*mes 108 asp.net certificate winhttp iis-7.5

我有一个ASP.NET应用程序访问证书存储区中的证书中的私钥.在Windows Server 2003上,我能够使用winhttpcertcfg.exe来授予对NETWORK SERVICE帐户的私钥访问权限.如何授予访问IIS 7.5网站中Windows Server 2008 R2上的证书存储(本地计算机\个人)中的证书中的私钥的权限?

我尝试使用证书MMC(Server 2008 R2)为"Everyone","IIS AppPool\DefaultAppPool","IIS_IUSRS"以及我能找到的每个其他安全帐户提供完全信任访问权限.但是,下面的代码演示了代码无法访问使用私钥导入的证书的私钥.每次访问私钥属性时,代码都会抛出并抛出错误.

Default.aspx的

<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" %>
<%@ Import Namespace="System.Security.Cryptography.X509Certificates" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title></title>
</head>
<body>
    <form id="form1" runat="server">
    <div>
        <asp:Repeater ID="repeater1" runat="server">
            <HeaderTemplate>
                <table>
                    <tr>
                        <td>
                            Cert
                        </td>
                        <td>
                            Public Key
                        </td>
                        <td>
                            Private Key
                        </td>
                    </tr>
            </HeaderTemplate>
            <ItemTemplate>
                <tr>
                    <td>
                    <%#((X509Certificate2)Container.DataItem).GetNameInfo(X509NameType.SimpleName, false) %>
                    </td>
                    <td>
                    <%#((X509Certificate2)Container.DataItem).HasPublicKeyAccess() %>
                    </td>
                    <td>
                    <%#((X509Certificate2)Container.DataItem).HasPrivateKeyAccess() %>
                    </td>
                </tr>
            </ItemTemplate>
            <FooterTemplate>
                </table></FooterTemplate>
        </asp:Repeater>
    </div>
    </form>
</body>
</html>

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";
    }
}
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" %>
<%@ Import Namespace="System.Security.Cryptography.X509Certificates" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title></title>
</head>
<body>
    <form id="form1" runat="server">
    <div>
        <asp:Repeater ID="repeater1" runat="server">
            <HeaderTemplate>
                <table>
                    <tr>
                        <td>
                            Cert
                        </td>
                        <td>
                            Public Key
                        </td>
                        <td>
                            Private Key
                        </td>
                    </tr>
            </HeaderTemplate>
            <ItemTemplate>
                <tr>
                    <td>
                    <%#((X509Certificate2)Container.DataItem).GetNameInfo(X509NameType.SimpleName, false) %>
                    </td>
                    <td>
                    <%#((X509Certificate2)Container.DataItem).HasPublicKeyAccess() %>
                    </td>
                    <td>
                    <%#((X509Certificate2)Container.DataItem).HasPrivateKeyAccess() %>
                    </td>
                </tr>
            </ItemTemplate>
            <FooterTemplate>
                </table></FooterTemplate>
        </asp:Repeater>
    </div>
    </form>
</body>
</html>

tha*_*mes 187

  1. 创建/购买证书.确保它有一个私钥.
  2. 将证书导入"本地计算机"帐户.最好使用证书MMC.确保选中"允许导出私钥"
  3. 基于此,IIS 7.5应用程序池的标识使用以下之一.

    • IIS 7.5网站在ApplicationPoolIdentity下运行.打开MMC =>添加证书(本地计算机)管理单元=>证书(本地计算机)=>个人=>证书=>右键单击感兴趣的证书=>所有任务=>管理私钥=>添加IIS AppPool\AppPoolName并授予它Full control.将" AppPoolName " 替换为应用程序池的名称(有时IIS_IUSRS)
    • IIS 7.5网站在NETWORK SERVICE下运行.使用证书MMC,在"本地计算机\个人"中的证书上将"网络服务"添加到完全信任.
    • IIS 7.5网站在"MyIISUser"本地计算机用户帐户下运行.使用证书MMC,在"本地计算机\个人"中的证书上将"MyIISUser"(新的本地计算机用户帐户)添加到完全信任.

基于@Phil Hale的更新评论:

请注意,如果您在某个域中,默认情况下会在"从位置框"中选择您的域名.务必将其更改为"本地计算机".将位置更改为"本地计算机"以查看应用程序池标识.

  • 当您将MMC证书打开到本地计算机\个人时,单击"证书"以查看证书.(注意:以下假设已导入证书,如果没有,则先导入证书)右键单击要授予完全控制权的证书.在上下文菜单中,单击"所有任务",然后在子菜单中单击"管理私钥".从那里,您可以添加您希望"读取"访问证书私钥的任何用户. (6认同)
  • 确保在"从位置"框中选择了本地计算机.这困扰了我一段时间.默认情况下选择了域,因此在将位置更改为本地计算机之前,它找不到应用程序池标识用户 (4认同)
  • 知道如何通过PowerShell做到这一点? (4认同)
  • 如何在Windows Server 2008 R2中配置("XXX"到"本地计算机\个人"中的证书上的完全信任)?运行/ mmc /文件/添加管理单元/证书和??? 谢谢 (3认同)
  • 在AWS的Windows 2012 R2 EC2 VM(基于IIS 8)上,您需要授予"IIS_IUSRS"访问证书私钥的权限 (3认同)

小智 42

关于通过MMC,Certs,Select Cert,右键单击,所有任务,"管理私钥"授予权限的注意事项

管理私人密钥仅在个人菜单列表中...因此,如果您已将您的证书放在受信任的人等中,那么您将失去运气.

我们找到了解决这个问题的方法,对我们有用.将证书拖放到Personal,执行Manage Private Keys事务以授予权限.请记住设置为使用对象类型内置函数并使用本地计算机而不是域.我们授予了DefaultAppPool用户的权限,并将其保留在那里.

完成后,将证书拖放回原来的位置.普雷斯托.

  • win2003服务器的任何解决方案?它没有像Windows 7那样的管理私钥作为选项 (2认同)

Sim*_*ver 12

如果您尝试从IIS中的.pfx文件加载证书,解决方案可能就像启用此选项一样简单Application Pool.

右键单击App Pool并选择Advanced Settings.

然后启用 Load User Profile


在此输入图像描述

  • 为什么这会产生影响? (3认同)
  • 它必须只是Windows连接的方式.它可能暂时将配置文件加载到用户配置文件中,因此需要此选项.我同意从IIS有权访问的文件加载时,这是很奇怪的. (2认同)

Ian*_*son 7

我想出了如何在Powershell中执行此操作,有人问过:

$keyname=(((gci cert:\LocalMachine\my | ? {$_.thumbprint -like $thumbprint}).PrivateKey).CspKeyContainerInfo).UniqueKeyContainerName
$keypath = $env:ProgramData + “\Microsoft\Crypto\RSA\MachineKeys\”
$fullpath=$keypath+$keyname

$Acl = Get-Acl $fullpath
$Ar = New-Object System.Security.AccessControl.FileSystemAccessRule("IIS AppPool\$iisAppPoolName", "Read", "Allow")
$Acl.SetAccessRule($Ar)
Set-Acl $fullpath $Acl
Run Code Online (Sandbox Code Playgroud)


Nat*_*ley 6

对我来说,只需重新导入证书并选中"允许导出私钥".

我想这是必要的,但它确实让我感到紧张,因为它是访问此证书的第三方应用程序.