从远程服务器读取证书哈希

时间:2012-03-06 15:26:17

标签: c# .net windows iis-7.5 wsastartup

尝试使用以下代码从远程计算机获取证书哈希时收到错误:

private string getCertHash(string Hostname)
{
    string result = "";

    using (ServerManager serverManager = ServerManager.OpenRemote(Hostname))
    {
        SiteCollection siteCollection = serverManager.Sites;
        foreach (Site site in siteCollection)
        {
            foreach (Binding binding in site.Bindings)
            {
                if (binding.Protocol == "https")
                {
                    // Error here
                    foreach (Byte certhashbyte in binding.CertificateHash)
                        result += certhashbyte.ToString(); 
                }
            }
        }
    }

    return result;
}

我收到的错误更详细:

  

'binding.certhashbyte'引发了类型异常   'System.Runtime.InteropServices.COMException'

     

应用程序未调用WSAStartup或WSAStartup   失败。 (HRESULT异常:0x8007276D)

如果我替换以下行:

using (ServerManager serverManager = ServerManager.OpenRemote(Hostname))

using (ServerManager serverManager = new ServerManager)

使用本地服务器它工作正常。

请注意,使用ServerManager.OpenRemote(Hostname)一般情况下(我获取所有其他信息,只有CertHash信息导致错误。我在两台计算机(本地和远程)上都拥有管理员权限。系统是Windows 2008 R2使用IIS 7.5。

请告诉我我做错了什么/缺少什么/错误发生的原因。

2 个答案:

答案 0 :(得分:2)

出于某种原因,上面的代码现在可以正常工作。我无法找出它为什么不起作用,但我确实找到了一些我想分享的选择:

  1. 使用this code,此处使用示例:

    CertStoreReader certStoreReader = new CertStoreReader();
    foreach (X509Certificate2 x509 in certStoreReader.GetCertificates(credentials.Hostname))
    {
        certHash = x509.GetCertHashString();
    }
    
  2. 首先使用ServerManager(在问题中)

    using (ServerManager serverManager = ServerManager.OpenRemote(server))
    {
        Site site = serverManager.Sites.Where(s => s.Name == websiteName).Single();
        foreach (Binding binding in site.Bindings)
        {
            certHash += BitConverter.ToString(binding.CertificateHash).Replace("-", string.Empty);      
        }              
    }
    
  3. 使用DirectoryEntry

    DirectoryEntry dir = new DirectoryEntry(@"IIS://" + server + @"/W3SVC/" + siteID);
    PropertyValueCollection vals = dir.Properties["SSLCertHash"];
    foreach (string entry in vals)
    {
        certHash += entry;
    }
    
  4. 使用WMI。我在WebAdministration名称空间中使用了此查询:

    "SELECT CertificateHash FROM SSLBinding WHERE IPAddress = '" + IP + "' AND Port = " + port
    

答案 1 :(得分:0)

或者您可以简单地做到:

using (var store = new X509Store(@"\\[RemoteMachineName]\My", StoreLocation.LocalMachine))
{
    store.Open(OpenFlags.ReadOnly);
    certificates = store.Certificates;
}

只需确保您具有访问远程计算机证书存储的正确权限。