我正在尝试使用 Request.ClientCertificate 读取 X509 证书,但没有返回任何内容。证书肯定附加到请求中,因为我可以从发送请求的页面获取证书信息。
我曾尝试从几个不同的地方阅读证书,但似乎无法让它发挥作用。
我从这篇知识库文章中的代码开始。在请求的页面中,我尝试打印出有关证书的一些信息,但响应中没有返回任何内容。
这是在 IIS 5.1 上运行的,并且通过 SSL 进行通信。这必须使用 .Net 框架的第 2 版来完成
为什么证书似乎消失了?
我正在尝试使用 Request.ClientCertificate 读取 X509 证书,但没有返回任何内容。证书肯定附加到请求中,因为我可以从发送请求的页面获取证书信息。
我曾尝试从几个不同的地方阅读证书,但似乎无法让它发挥作用。
我从这篇知识库文章中的代码开始。在请求的页面中,我尝试打印出有关证书的一些信息,但响应中没有返回任何内容。
这是在 IIS 5.1 上运行的,并且通过 SSL 进行通信。这必须使用 .Net 框架的第 2 版来完成
为什么证书似乎消失了?
不久前,我写了一个识别网页,用于查找客户端证书,如果找到,将显示证书信息。我相信这就是您正在寻找的......这是页面:
<%@ Page Language="C#" Trace="false" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<%@ Import Namespace="System.Security.Cryptography.X509Certificates" %>
<%@ Import Namespace="System.Security.Cryptography" %>
<script runat="server">
//protected void Page_Load(object sender, EventArgs e)
//{ }
void LoadCertInfo()
{
string para = "<div style='margin: 10px 0 0 0; font-weight: bold'>{0}</div>";
string subpara = "<div style='margin-left: 15px; font-size: 90%'>{0}</div>";
if (Page.Request.ClientCertificate.IsPresent)
{
Response.Write("<hr /><div style='width: 500px; margin: 20px auto'>");
Response.Write("<h3 style='width: 500px; margin: 20px auto'>Client Certificate Information</h3>");
try
{
X509Certificate2 x509Cert2 = new X509Certificate2(Page.Request.ClientCertificate.Certificate);
Response.Write(string.Format(para, "Issued To:"));
Response.Write(string.Format(subpara, x509Cert2.Subject));
Response.Write(string.Format(para, "Issued By:"));
Response.Write(string.Format(subpara, x509Cert2.Issuer));
Response.Write(string.Format(para, "Friendly Name:"));
Response.Write(string.Format(subpara, string.IsNullOrEmpty(x509Cert2.FriendlyName) ? "(None Specified)" : x509Cert2.FriendlyName));
Response.Write(string.Format(para, "Valid Dates:"));
Response.Write(string.Format(subpara, "From: " + x509Cert2.GetEffectiveDateString()));
Response.Write(string.Format(subpara, "To: " + x509Cert2.GetExpirationDateString()));
Response.Write(string.Format(para, "Thumbprint:"));
Response.Write(string.Format(subpara, x509Cert2.Thumbprint));
//Response.Write(string.Format(para, "Public Key:"));
//Response.Write(string.Format(subpara, x509Cert2.GetPublicKeyString()));
#region EKU Section - Retrieve EKU info and write out each OID
X509EnhancedKeyUsageExtension ekuExtension = (X509EnhancedKeyUsageExtension)x509Cert2.Extensions["Enhanced Key Usage"];
if (ekuExtension != null)
{
Response.Write(string.Format(para, "Enhanced Key Usages (" + ekuExtension.EnhancedKeyUsages.Count.ToString() + " found)"));
OidCollection ekuOids = ekuExtension.EnhancedKeyUsages;
foreach (Oid ekuOid in ekuOids)
Response.Write(string.Format(subpara, ekuOid.FriendlyName + " (OID: " + ekuOid.Value + ")"));
}
else
{
Response.Write(string.Format(para, "No EKU Section Data"));
}
#endregion // EKU Section
#region Subject Alternative Name Section
X509Extension sanExtension = (X509Extension)x509Cert2.Extensions["Subject Alternative Name"];
if (sanExtension != null)
{
Response.Write(string.Format(para, "Subject Alternative Name:"));
Response.Write(string.Format(subpara, sanExtension.Format(true)));
}
else
{
Response.Write(string.Format(para, "No Subject Alternative Name Data"));
}
#endregion // Subject Alternative Name Section
#region Certificate Policies Section
X509Extension policyExtension = (X509Extension)x509Cert2.Extensions["Certificate Policies"];
if (policyExtension != null)
{
Response.Write(string.Format(para, "Certificate Policies:"));
Response.Write(string.Format(subpara, policyExtension.Format(true)));
}
else
{
Response.Write(string.Format(para, "No Certificate Policies Data"));
}
#endregion //Certificate Policies Section
// Example on how to enumerate all extensions
//foreach (X509Extension extension in x509Cert2.Extensions)
// Response.Write(string.Format(para, extension.Oid.FriendlyName + "(" + extension.Oid.Value + ")"));
}
catch (Exception ex)
{
Response.Write(string.Format(para, "An error occured:"));
Response.Write(string.Format(subpara, ex.Message));
Response.Write(string.Format(subpara, ex.StackTrace));
}
finally
{
Response.Write("</div>");
}
}
}
</script>
<html>
<head runat="server">
<title><% Page.Response.Write(System.Environment.MachineName); %></title>
</head>
<body>
<% LoadCertInfo(); %>
</body>
</html>
我不确定您需要客户端证书的用途,但如果您将其用于您自己的自定义身份验证或授权,您可能需要考虑使用 Web 服务器的安全基础架构,而不是实现自己的。例如,您可以将 IIS 配置为需要客户端证书,将证书映射到用户帐户,并使用基于 Windows 的身份验证。当然,这不一定适用于您的问题域。
好的,这并不完全清楚,但是您有一个网站要求客户使用证书进行身份验证?因为这就是Request.ClientCertificate
房产的用途。
我这样说是因为你的问题有些奇怪。
“我可以从发送请求的页面获取证书信息。”
页面通常不会真正发送客户端所做的请求。
要获得服务器证书,您可以打开 X509Store 并筛选证书以找到您需要的 CN。
您必须将本地 IIS 配置为接受(或要求)客户端证书。