Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
||
ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
[3.143.228.40] |
|
Сообщ.
#1
,
|
|
|
Доброго времени суток.
Создал корневой, серверный и клиентский сертификаты с помощью утилиты makecert. Установил их. Взял пример http://msdn.microsoft.com/en-us/library/system.net.security.sslstream(v=vs.80).aspx Код сервера public static void RunServer(string certificate) { X509Store store = new X509Store(StoreName.My, StoreLocation.LocalMachine); store.Open(OpenFlags.ReadOnly); X509CertificateCollection cert = store.Certificates.Find(X509FindType.FindBySubjectName, "Server", false); serverCertificate = cert[0]; TcpListener listener = new TcpListener(IPAddress.Any, 443); listener.Start(); while (true) { Console.WriteLine("Waiting for a client to connect..."); TcpClient client = listener.AcceptTcpClient(); ProcessClient(client); } } static void ProcessClient(TcpClient client) { SslStream sslStream = new SslStream( client.GetStream(), false, new RemoteCertificateValidationCallback(ValidateClientCertificate)); // <---- Добавил проверку сертификата клиента try { sslStream.AuthenticateAsServer(serverCertificate, true, SslProtocols.Default, false); DisplaySecurityLevel(sslStream); DisplaySecurityServices(sslStream); DisplayCertificateInformation(sslStream); DisplayStreamProperties(sslStream); sslStream.ReadTimeout = 5000; sslStream.WriteTimeout = 5000; Console.WriteLine("Waiting for client message..."); string messageData = ReadMessage(sslStream); Console.WriteLine("Received: {0}", messageData); byte[] message = Encoding.UTF8.GetBytes("Hello from the server.<EOF>"); Console.WriteLine("Sending hello message."); sslStream.Write(message); } catch (AuthenticationException e) { Console.WriteLine("Exception: {0}", e.Message); if (e.InnerException != null) { Console.WriteLine("Inner exception: {0}", e.InnerException.Message); } Console.WriteLine("Authentication failed - closing the connection."); sslStream.Close(); client.Close(); return; } finally { sslStream.Close(); client.Close(); } public static bool ValidateClientCertificate( object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors) { SslPolicyErrors errors = sslPolicyErrors; if (errors != SslPolicyErrors.None) { Console.WriteLine("Certificate error: {0} ", errors); } if (((errors & SslPolicyErrors.RemoteCertificateChainErrors) == SslPolicyErrors.RemoteCertificateChainErrors)) { errors -= SslPolicyErrors.RemoteCertificateChainErrors; } if (((errors & SslPolicyErrors.RemoteCertificateNameMismatch) == SslPolicyErrors.RemoteCertificateNameMismatch)) { errors -= SslPolicyErrors.RemoteCertificateNameMismatch; } if (errors == SslPolicyErrors.None) return true; Console.WriteLine("Certificate error: {0}", sslPolicyErrors); return false; } Код клиента public static bool ValidateServerCertificate( object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors) { if (sslPolicyErrors == SslPolicyErrors.None) return true; return false; } public static void RunClient(string machineName, string serverName) { X509Store store = new X509Store(StoreName.My, StoreLocation.CurrentUser); store.Open(OpenFlags.ReadOnly); X509CertificateCollection cert = store.Certificates.Find(X509FindType.FindBySubjectName, "Server", false); TcpClient client = new TcpClient(machineName, 443); Console.WriteLine("Client connected."); SslStream sslStream = new SslStream( client.GetStream(), false, new RemoteCertificateValidationCallback(ValidateServerCertificate), null ); try { sslStream.AuthenticateAsClient(serverName, cert, SslProtocols.Default, false); } catch (AuthenticationException e) { Console.WriteLine("Exception: {0}", e.Message); if (e.InnerException != null) { Console.WriteLine("Inner exception: {0}", e.InnerException.Message); } Console.WriteLine("Authentication failed - closing the connection."); client.Close(); return; } byte[] messsage = Encoding.UTF8.GetBytes("Hello from the client.<EOF>"); sslStream.Write(messsage); sslStream.Flush(); string serverMessage = ReadMessage(sslStream); Console.WriteLine("Server says: {0}", serverMessage); client.Close(); Console.WriteLine("Client closed."); } Клиент проверяет сервер и подключается, а вот серверу никак не хочет подключать клиента. Чтобы я не пробовал - выдает постоянно ошибку RemoteCertificateNotAvailable - Удаленный сертификат недействителен согласно результатам проверки подлинности. Можете подсказать, что не так? куда копать? Добавлено Поторопился с постом, надо было просто добавить в код клиента и сервера public static X509Certificate ValidateClientCertificate( object sender, string targetHost, X509CertificateCollection localCertificates, X509Certificate remoteCertificate, string[] acceptableIssuers) { Console.WriteLine(" > Client is selecting a local certificate."); if (acceptableIssuers != null && acceptableIssuers.Length > 0 && localCertificates != null && localCertificates.Count > 0) { // Use the first certificate that is from an acceptable issuer. foreach (X509Certificate certificate in localCertificates) { string issuer = certificate.Issuer; if (Array.IndexOf(acceptableIssuers, issuer) != -1) return certificate; } } if (localCertificates != null && localCertificates.Count > 0) return localCertificates[0]; return null; } // SslStream создается теперь так ... SslStream sslStream = new SslStream( client.GetStream(), false, new RemoteCertificateValidationCallback(ValidateServerCertificate), new LocalCertificateSelectionCallback(ValidateClientCertificate)); ... |