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

本文关键字:读取 证书 哈希 服务器 | 更新日期: 2023-09-27 18:26:49

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

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(主机名)通常可以正常工作(我得到所有其他信息,只有CertHash信息会导致错误。我在这两台机器(本地和远程)上都有管理员权限。系统是使用IIS 7.5的Windows 2008 R2。

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

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

由于某些原因,上面的代码现在可以正常工作。我不知道为什么它不起作用,但我确实找到了一些我想分享的替代方案:

  1. 使用此代码和这里的示例用法:

    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
    

或者您可以简单地执行:

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

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