如何让ASP.NET访问证书存储中的证书中的私钥? [英] How to give ASP.NET access to a private key in a certificate in the certificate store?

查看:246
本文介绍了如何让ASP.NET访问证书存储中的证书中的私钥?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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



我试过给予完全信任访问所有人,IIS AppPool \DefaultAppPool,IIS_IUSRS和我可以找到使用证书MMC(服务器2008 R2)的每一个安全帐户。但是下面的代码演示了代码不能访问使用私钥导入的证书的私钥。



Default.aspx
pre><%@ Page Language =C#AutoEventWireup =trueCodeFile =Default.aspx.csInherits =_ 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 =form1runat =server>
< div>
< asp:Repeater ID =repeater1runat =server>
< HeaderTemplate>
< table>
< tr> ¥b $ b< td>
Cert
< / td>
< td>
公钥
< / td>
< td>
私钥
< / td>
< / tr>
< 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>



Default.aspx.cs

 
使用System;
using System.Security.Cryptography;
using System.Security.Cryptography.X509Certificates;
使用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);
//创建并打开只读访问的存储
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)
{
returnNo;
}
returnYes;
}
public static string HasPrivateKeyAccess(this X509Certificate2 cert)
{
try
{
string algorithm = cert.PrivateKey.KeyExchangeAlgorithm;
}
catch(Exception ex)
{
returnNo;
}
returnYes;
}
}


解决方案


  1. 创建/购买证书。确保其具有私钥。

  2. 将证书导入到本地计算机帐户。最好使用证书MMC。 请务必选中允许导出私钥

  3. 基于此,IIS 7.5应用程序池的身份可使用以下方法之一。 p>


    • IIS 7.5网站正在ApplicationPoolIdentity下运行。打开MMC =>添加证书(本地计算机)管理单元=>证书(本地计算机)=>个人=>证书=>右键单击感兴趣的证书=>所有任务=>管理私钥=>添加 IIS AppPool\AppPoolName 并授予完全控制。将 AppPoolName 替换为您的应用程序池名称(有时 IIS_IUSRS

    • IIS 7.5网站在网络服务下运行。使用证书MMC,在本地计算机\个人证书中添加了网络服务以完全信任。

    • IIS 7.5网站在MyIISUser本地计算机用户帐户下运行。使用证书MMC,将MyIISUser(新的本地计算机用户帐户)添加到本地计算机\个人证书中的完全信任。



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?

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.

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>

Default.aspx.cs

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";
    }
}

解决方案

  1. Create / Purchase certificate. Make sure it has a private key.
  2. Import the certificate into the "Local Computer" account. Best to use Certificates MMC. Make sure to check "Allow private key to be exported"
  3. Based upon which, IIS 7.5 Application Pool's identity use one of the following.

    • IIS 7.5 Website is running under ApplicationPoolIdentity. Open MMC => Add Certificates (Local computer) snap-in => Certificates (Local Computer) => Personal => Certificates => Right click the certificate of interest => All tasks => Manage private key => Add IIS AppPool\AppPoolName and grant it Full control. Replace "AppPoolName" with the name of your application pool (sometimes IIS_IUSRS)
    • IIS 7.5 Website is running under NETWORK SERVICE. Using Certificates MMC, added "NETWORK SERVICE" to Full Trust on certificate in "Local Computer\Personal".
    • IIS 7.5 Website is running under "MyIISUser" local computer user account. Using Certificates MMC, added "MyIISUser" (a new local computer user account) to Full Trust on certificate in "Local Computer\Personal".

这篇关于如何让ASP.NET访问证书存储中的证书中的私钥?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆