У меня есть клиентское и серверное приложение, которое использует SSLStream для связи через порт 80. И клиент, и сервер работают как службы Windows.
Все работает в моей тестовой среде (мой компьютер для разработки, под ОС 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];
}
В-третьих, На сервере я начинаю прослушивать TCP-клиенты через порт 80:
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);
-- Выше всего, что у меня есть в связи с этой проблемой -