我有一个客户端和服务器应用程序,它使用 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);
-- 以上是我与这个问题相关的所有信息 --