如何让 ASP.NET 访问证书存储中的证书中的私钥?
我有一个 ASP.NET 应用程序,它访问证书存储中证书中的私钥。在 Windows Server 2003 上,我能够使用 winhttpcertcfg.exe 授予对 NETWORK SERVICE 帐户的私钥访问权限。如何授予访问 IIS 7.5 网站中 Windows Server 2008 R2 上证书存储(本地计算机\个人)中证书中私钥的权限?
我尝试向“Everyone”、“IIS AppPool\DefaultAppPool”、“IIS_IUSRS”以及我可以使用证书 MMC (Server 2008 R2) 找到的所有其他安全帐户授予完全信任访问权限。但是,下面的代码表明该代码无权访问使用私钥导入的证书的私钥。每次访问私钥属性时,代码都会抛出错误。
默认.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>
默认.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";
}
}
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"; } }
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(7)
基于此,IIS 7.5 应用程序池的标识将使用以下其中一项。
IIS AppPool\AppPoolName
并授予其完全控制权
。将“AppPoolName”替换为您的应用程序池的名称(有时IIS_IUSRS
)根据 @Phil Hale 评论进行更新:
请注意,如果您位于某个域中,则默认情况下将在“来自位置框”中选择您的域。确保将其更改为“本地计算机”。将位置更改为“本地计算机”以查看应用程序池标识。
Based upon which, IIS 7.5 Application Pool's identity use one of the following.
IIS AppPool\AppPoolName
and grant itFull control
. Replace "AppPoolName" with the name of your application pool (sometimesIIS_IUSRS
)Update based upon @Phil Hale comment:
Beware, if you're on a domain, your domain will be selected by default in the 'from location box'. Make sure to change that to "Local Computer". Change the location to "Local Computer" to view the app pool identities.
有关通过 MMC、证书、选择证书、右键单击、所有任务、“管理私钥”授予权限的注意事项
管理私钥仅位于“个人”的菜单列表中...因此,如果您已将证书放入“受信任的人”中等等,你运气不好。
我们找到了一种对我们有用的解决方法。将证书拖放到个人中,执行管理私钥操作以授予权限。请记住设置为使用对象类型内置程序并使用本地计算机而不是域。我们向 DefaultAppPool 用户授予了权限,然后就保留了该权限。
完成后,将证书拖放到原来的位置。急速。
Note on granting permissions via MMC, Certs, Select Cert, right-click, all-tasks, "Manage Private Keys"
Manage Private Keys is only on the menu list for Personal... So if you've put your cert in Trusted People, etc. you're out of luck.
We found a way around this which worked for us. Drag and drop the cert to Personal, do the Manage Private Keys thing to grant permissions. Remember to set to use object-type built-ins and use the local machine not domain. We granted rights to the DefaultAppPool user and left it at that.
Once you're done, drag and drop the cert back where ever you originally had it. Presto.
如果您尝试从 IIS 中的 .pfx 文件加载证书,解决方案可能就像为
应用程序池
启用此选项一样简单。右键单击应用程序池并选择
高级设置
。然后启用
加载用户配置文件
If you are trying to load a cert from a .pfx file in IIS the solution may be as simple as enabling this option for the
Application Pool
.Right click on the App Pool and select
Advanced Settings
.Then enable
Load User Profile
我想出了如何在 Powershell 中做到这一点,有人问:
I figured out how to do this in Powershell that someone asked about:
对我来说,这无非是重新导入证书并选中“允许导出私钥”。
我想这是必要的,但它确实让我感到紧张,因为它是访问此证书的第三方应用程序。
For me, it was nothing more than re-importing the certificate with "Allow private key to be exported" checked.
I guess it is necessary, but it does make me nervous as it is a third party app accessing this certificate.
虽然我参加了上面的活动,但我是经过多次尝试才走到这一步的。
1-如果您想从商店访问证书,您可以这样做作为示例
2-生成证书并通过路径使用它更加容易和干净
Asp.net Core 2.2
或 1:
或 2:
Although I have attended the above, I have come to this point after many attempts.
1- If you want access to the certificate from the store, you can do this as an example
2- It is much easier and cleaner to produce the certificate and use it via a path
Asp.net Core 2.2
OR1:
OR 2:
在证书面板中,右键单击某个证书 ->所有任务->管理私钥->添加具有完全控制权的 IIS_IUSRS 用户
在我的情况下,我不需要安装我的证书并选中“允许导出私钥”选项,就像其他答案中所述。
In Certificates Panel, right click some certificate -> All tasks -> Manage private key -> Add IIS_IUSRS User with full control
In my case, I didnt't need to install my certificate with "Allow private key to be exported" option checked, like said in other answers.