1

我有一个客户端和服务器应用程序,它使用 SSLStream 通过端口 80 进行通信。客户端和服务器都作为 Windows 服务运行。

一切都在我的测试环境中运行(我的开发计算机,在 OS Windows 7 Ultimate 下)。我的问题是,当我将客户端和服务器应用程序部署到他们的部署环境(服务器在 Windows Server 2008 上,客户端在 Windows Server 2003 上)时,它不起作用,我收到错误消息:“客户端和服务器无法通信,因为它们不具备通用算法”请注意,我使用 makecert 命令安装了相同的证书(在下面的“首先”部分列出)

此外,当我放弃尝试让客户端在 Windows Server 2003 计算机下进行身份验证时,我将其移至全新/不同的 Windows Server 2008 计算机..然后出现“提供的凭据”的新错误包裹无法识别。”

如果您对这个问题有任何经验,请提供建议。在过去的 3 天里,我一直在研究这个问题,并且已经花费了 20 多个小时的开发时间。请记住,当服务器和客户端尝试进行身份验证时,问题一直在发生。

首先,我通过 makecert.exe 使用以下命令生成自签名 (?) X509 证书:

- makecert -n "CN=Transcert" -r -sv Transcert.pvk Transcert.cer
- makecert -sk Transcert -iv Transcert.pvk -n "CN=Transcert" -ic Transcert.cer Transcert.cer -sr LocalMachine -ss Root 

(请注意,我使用了存储位置“LocalMachine”,因为据我了解,Windows 服务通过 LocalSystem 帐户使用此存储位置,我可能错了吗?)

其次,在服务器上,我通过以下代码从商店中检索认证:

X509Store store = new X509Store(StoreName.Root, StoreLocation.LocalMachine);
store.Open(OpenFlags.ReadOnly);
X509CertificateCollection cert = store.Certificates.Find(X509FindType.FindBySubjectName, "Transcert", false);
if (cert.Count > 0)
{
  return cert[0];
}

第三,在服务器上,我开始在端口 80 上监听 TCP 客户端:

public virtual void StartListening()
{
  sslServer = new TcpListener(HostPort);

  sslServer.Start();

  AcceptClientThread = new Thread(new ThreadStart(AcceptClientThread_Run));
  AcceptClientThread.Start();
}

private void AcceptClientThread_Run()
{
  try
  {
    TcpClient client = sslServer.AcceptTcpClient();

    ProcessNewClient(client);
  }
  catch (Exception ex)
  {

  }

  AcceptClientThread_Run();
}

第四,在服务器上,我准备了客户端连接时要处理的代码:

  SslClient = pSslClient;
  SSLCertificate = pSSLCertificate;

  _SslStream = new SslStream(SslClient.GetStream());
  _SslStream.AuthenticateAsServer(SSLCertificate, false, SslProtocols.Tls, false);

  Output = new StreamWriter(_SslStream);
  Output.AutoFlush = true;
  Input = new StreamReader(_SslStream);

  ReadThread = new Thread(new ThreadStart(ReadIncomingData));
  ReadThread.Start();

最后,在客户端,我准备了将客户端连接到服务器的代码:

    ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls | SecurityProtocolType.Ssl3;

    sslClient = new TcpClient();
    sslClient.Connect(HostAddress, HostPort);

    //ServicePointManager.ServerCertificateValidationCallback = delegate(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors) { return true; };

    sslStream = new SslStream(sslClient.GetStream(), false, new RemoteCertificateValidationCallback(CertificateValidationCallback));
    sslStream.AuthenticateAsClient("Trancert");

    showSslInfo(HostAddress, sslStream, true);

-- 以上是我与这个问题相关的所有信息 --

4

1 回答 1

1

如果相同的代码在一台机器上运行而不是在另一台机器上运行,并且具有相同的服务器证书,那么我会仔细检查私钥是否与第二台机器上的服务器证书一起正确导入。

查看证书管理器 MMC 管理单元中的证书属性,您应该会在“您有一个与此证书对应的私钥”旁边看到一个小钥匙图标。

于 2010-12-08T09:48:33.803 回答