1

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

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 信息会导致错误。我在两台机器(本地和远程)上都拥有管理员权限。系统是使用 IIS 7.5 的 Windows 2008 R2 .

请告诉我我做错了什么/缺少什么/为什么会发生错误。

4

2 回答 2

2

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

  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
    
于 2012-03-14T09:30:13.320 回答
0

或者你可以简单地做:

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

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

于 2019-05-02T22:02:51.763 回答