如何从特定绑定 C# 获取证书
How to get certificate from specific binding C#
我在互联网上找到了从 iis 获取所有证书的唯一方法,我按照以下方式 (c#) 进行操作:
var store = new X509Store(StoreName.My, StoreLocation.LocalMachine);
store.Open(OpenFlags.ReadOnly);
store.Certificates;
现在我尝试获取特定绑定的特定证书,在 C# 中如何实现?
以下link应该有所帮助:
基本上 store.Certificates returns 特定商店中所有证书的集合,然后您可以搜索所需的证书。 link 显示了如果您知道所需证书的主题名称,如何执行此操作。
How to get X509Certificate from certificate store and generate xml signature data?
证书本身绝对不包含有关 IIS 中使用的绑定的信息,因此您无法从计算机检索证书并期望它们包含与 IIS 相关的任何信息。您需要从 IIS 查询该信息。
为此,您需要添加对可在 %windir%\system32\inetsrv\Microsoft.Web.Administration.dll
下找到的库的引用(注意:必须安装 IIS 7 或更高版本)。在此之后,您可以执行以下操作来获取证书:
ServerManager manager = new ServerManager();
Site yourSite = manager.Sites["yourSiteName"];
X509Certificate2 yourCertificate = null;
foreach (Binding binding in yourSite.Bindings)
{
if (binding.Protocol == "https" && binding.EndPoint.ToString() == "127.0.0.1" /*your binding IP*/)
{
var store = new X509Store(StoreName.My, StoreLocation.LocalMachine);
store.Open(OpenFlags.ReadOnly);
yourCertificate = store.Certificates.Find(X509FindType.FindByThumbprint, ToHex(binding.CertificateHash), true)[0];
break;
}
}
public static string ToHex(byte[] ba)
{
var hex = new StringBuilder(ba.Length * 2);
foreach (byte b in ba)
{
hex.AppendFormat("{0:x2}", b);
}
return hex.ToString();
}
我觉得卡米洛的回答有点小问题。据我所知(已测试)查找证书的代码不起作用,因为 System.Convert.ToBase64String(binding.CertificateHash)
没有 return 有效的证书指纹。
我的版本:
/// <summary>
/// Returns the https certificate used for a given local IIS website.
/// </summary>
/// <param name="sWebsite">Website url, e.g., "https://myserver.company.com"</param>
/// <returns>certificate, null if not found</returns>
private X509Certificate2 FindIisHttpsCert(string sWebsite)
{
Uri uriWebsite = new Uri(sWebsite);
using (ServerManager sm = new ServerManager())
{
string sBindingPort = string.Format(":{0}:", uriWebsite.Port);
Binding bdBestMatch = null;
foreach (Site s in sm.Sites)
{
foreach (Binding bd in s.Bindings)
{
if (bd.BindingInformation.IndexOf(sBindingPort) >= 0)
{
string sBindingHostInfo = bd.BindingInformation.Substring(bd.BindingInformation.LastIndexOf(':') + 1);
if (uriWebsite.Host.IndexOf(sBindingHostInfo, StringComparison.InvariantCultureIgnoreCase) == 0)
{
if ((bd.Protocol == "https") && ((bdBestMatch == null) || (bdBestMatch.BindingInformation.Length < bd.BindingInformation.Length)))
bdBestMatch = bd;
}
}
}
}
if (bdBestMatch != null)
{
StringBuilder sbThumbPrint = new StringBuilder();
for (int i = 0; i < bdBestMatch.CertificateHash.Length; i++)
sbThumbPrint.AppendFormat("{0:X2}", bdBestMatch.CertificateHash[i]);
X509Store store = new X509Store(bdBestMatch.CertificateStoreName, StoreLocation.LocalMachine);
store.Open(OpenFlags.ReadOnly);
X509Certificate2Collection coll = store.Certificates.Find(X509FindType.FindByThumbprint, sbThumbPrint.ToString(), true);
if (coll.Count > 0)
return coll[0];
}
}
return null; // if no matching site was found
}
如果多个 https 站点托管在同一台服务器上(已测试),此功能也有效,如果站点使用 443 以外的端口(未测试),则该功能应该有效。要获取绑定信息,请使用 %windir%\system32\inetsrv\Microsoft.Web.Administration.dll
,如 Camilo 的回答。
我已经尝试过该解决方案,但 运行 遇到找不到证书的问题。最终是需要根据绑定正确指定证书存储:
ServerManager manager = new ServerManager();
Site yourSite = manager.Sites["yourSiteName"];
X509Certificate2 yourCertificate = null;
foreach (Binding binding in yourSite.Bindings)
{
if (binding.Protocol == "https" && binding.EndPoint.ToString() == "127.0.0.1" /*your binding IP*/)
{
var store = new X509Store(binding.CertificateStoreName, StoreLocation.LocalMachine);
store.Open(OpenFlags.ReadOnly);
var certs = store.Certificates.Find(X509FindType.FindByThumbprint, ToHex(binding.CertificateHash), true);
if (certs.Count > 0)
yourCertificate = certs[0];
break;
}
}
public static string ToHex(byte[] ba)
{
var hex = new StringBuilder(ba.Length * 2);
foreach (byte b in ba)
{
hex.AppendFormat("{0:x2}", b);
}
return hex.ToString();
}
我在互联网上找到了从 iis 获取所有证书的唯一方法,我按照以下方式 (c#) 进行操作:
var store = new X509Store(StoreName.My, StoreLocation.LocalMachine);
store.Open(OpenFlags.ReadOnly);
store.Certificates;
现在我尝试获取特定绑定的特定证书,在 C# 中如何实现?
以下link应该有所帮助:
基本上 store.Certificates returns 特定商店中所有证书的集合,然后您可以搜索所需的证书。 link 显示了如果您知道所需证书的主题名称,如何执行此操作。
How to get X509Certificate from certificate store and generate xml signature data?
证书本身绝对不包含有关 IIS 中使用的绑定的信息,因此您无法从计算机检索证书并期望它们包含与 IIS 相关的任何信息。您需要从 IIS 查询该信息。
为此,您需要添加对可在 %windir%\system32\inetsrv\Microsoft.Web.Administration.dll
下找到的库的引用(注意:必须安装 IIS 7 或更高版本)。在此之后,您可以执行以下操作来获取证书:
ServerManager manager = new ServerManager();
Site yourSite = manager.Sites["yourSiteName"];
X509Certificate2 yourCertificate = null;
foreach (Binding binding in yourSite.Bindings)
{
if (binding.Protocol == "https" && binding.EndPoint.ToString() == "127.0.0.1" /*your binding IP*/)
{
var store = new X509Store(StoreName.My, StoreLocation.LocalMachine);
store.Open(OpenFlags.ReadOnly);
yourCertificate = store.Certificates.Find(X509FindType.FindByThumbprint, ToHex(binding.CertificateHash), true)[0];
break;
}
}
public static string ToHex(byte[] ba)
{
var hex = new StringBuilder(ba.Length * 2);
foreach (byte b in ba)
{
hex.AppendFormat("{0:x2}", b);
}
return hex.ToString();
}
我觉得卡米洛的回答有点小问题。据我所知(已测试)查找证书的代码不起作用,因为 System.Convert.ToBase64String(binding.CertificateHash)
没有 return 有效的证书指纹。
我的版本:
/// <summary>
/// Returns the https certificate used for a given local IIS website.
/// </summary>
/// <param name="sWebsite">Website url, e.g., "https://myserver.company.com"</param>
/// <returns>certificate, null if not found</returns>
private X509Certificate2 FindIisHttpsCert(string sWebsite)
{
Uri uriWebsite = new Uri(sWebsite);
using (ServerManager sm = new ServerManager())
{
string sBindingPort = string.Format(":{0}:", uriWebsite.Port);
Binding bdBestMatch = null;
foreach (Site s in sm.Sites)
{
foreach (Binding bd in s.Bindings)
{
if (bd.BindingInformation.IndexOf(sBindingPort) >= 0)
{
string sBindingHostInfo = bd.BindingInformation.Substring(bd.BindingInformation.LastIndexOf(':') + 1);
if (uriWebsite.Host.IndexOf(sBindingHostInfo, StringComparison.InvariantCultureIgnoreCase) == 0)
{
if ((bd.Protocol == "https") && ((bdBestMatch == null) || (bdBestMatch.BindingInformation.Length < bd.BindingInformation.Length)))
bdBestMatch = bd;
}
}
}
}
if (bdBestMatch != null)
{
StringBuilder sbThumbPrint = new StringBuilder();
for (int i = 0; i < bdBestMatch.CertificateHash.Length; i++)
sbThumbPrint.AppendFormat("{0:X2}", bdBestMatch.CertificateHash[i]);
X509Store store = new X509Store(bdBestMatch.CertificateStoreName, StoreLocation.LocalMachine);
store.Open(OpenFlags.ReadOnly);
X509Certificate2Collection coll = store.Certificates.Find(X509FindType.FindByThumbprint, sbThumbPrint.ToString(), true);
if (coll.Count > 0)
return coll[0];
}
}
return null; // if no matching site was found
}
如果多个 https 站点托管在同一台服务器上(已测试),此功能也有效,如果站点使用 443 以外的端口(未测试),则该功能应该有效。要获取绑定信息,请使用 %windir%\system32\inetsrv\Microsoft.Web.Administration.dll
,如 Camilo 的回答。
我已经尝试过该解决方案,但 运行 遇到找不到证书的问题。最终是需要根据绑定正确指定证书存储:
ServerManager manager = new ServerManager();
Site yourSite = manager.Sites["yourSiteName"];
X509Certificate2 yourCertificate = null;
foreach (Binding binding in yourSite.Bindings)
{
if (binding.Protocol == "https" && binding.EndPoint.ToString() == "127.0.0.1" /*your binding IP*/)
{
var store = new X509Store(binding.CertificateStoreName, StoreLocation.LocalMachine);
store.Open(OpenFlags.ReadOnly);
var certs = store.Certificates.Find(X509FindType.FindByThumbprint, ToHex(binding.CertificateHash), true);
if (certs.Count > 0)
yourCertificate = certs[0];
break;
}
}
public static string ToHex(byte[] ba)
{
var hex = new StringBuilder(ba.Length * 2);
foreach (byte b in ba)
{
hex.AppendFormat("{0:x2}", b);
}
return hex.ToString();
}