2012-03-06 2 views
5

Моя цель - обеспечить безопасную связь между сервером Java и клиентом, написанным на C#.Связь SSL между приложениями Java и C#

код сервера

Java:

System.setProperty("javax.net.ssl.keyStore","cert/mySrvKeystore"); 
    System.setProperty("javax.net.ssl.keyStorePassword","myPassword"); 

    SSLServerSocketFactory sslserversocketfactory = 
      (SSLServerSocketFactory) SSLServerSocketFactory.getDefault(); 
    SSLServerSocket sslserversocket = = (SSLServerSocket) sslserversocketfactory.createServerSocket(2389); 

    while(true) { 
    System.err.println("server w8 new connection"); 
    try { 

      SSLSocket sslsocket = (SSLSocket) sslserversocket.accept(); 
      //sslsocket.startHandshake(); 

      in = sslsocket.getInputStream(); 
      out = sslsocket.getOutputStream(); 
      out.flush(); 

      String response = new String(receiveMessage()); 
      while (response != "end") { 
       System.out.println("Server recv="+response); 
       response = new String(receiveMessage()); 
       sendMessage(("echo="+response).getBytes()); 
      } 
     } catch (Exception exception) { 
      exception.printStackTrace(); 
     } 
    } 

и клиент, написанный на C#:

 client = new TcpClient() { SendTimeout = 5000, ReceiveTimeout = 5000 }; 
     IPEndPoint serverEndPoint = new IPEndPoint(IPAddress.Parse(host), port); 

     client.Connect(serverEndPoint); 
     client.NoDelay = true; 
     Console.WriteLine("Client connected."); 

     // Create an SSL stream that will close the client's stream. 
     SslStream sslStream = new SslStream(client.GetStream(), false, ValidateServerCertificate, null); 
     // The server name must match the name on the server certificate. 
     try 
     { 
      sslStream.AuthenticateAsClient("someName"); 
     } 
     catch (AuthenticationException error) 
     { 
      Console.WriteLine("Exception: {0}", error.Message); 
      if (error.InnerException != null) 
      { 
       Console.WriteLine("Inner exception: {0}", error.InnerException.Message); 
      } 
      Console.WriteLine("Authentication failed - closing the connection."); 
      client.Close(); 
      return; 
     } 

     ASCIIEncoding ascii = new ASCIIEncoding(); 
     SendData(ascii.GetBytes("Hello World"));  

и

public static bool ValidateServerCertificate(
      object sender, 
      X509Certificate certificate, 
      X509Chain chain, 
      SslPolicyErrors sslPolicyErrors) 
    { 
     if (sslPolicyErrors == SslPolicyErrors.None) 
      return true; 

     Console.WriteLine("Certificate error: {0}", sslPolicyErrors); 

     // Do not allow this client to communicate with unauthenticated servers. 
     return false; 
    } 

и я получаю следующие ошибки: в C#

A first chance exception of type "System.Security.Authentication.AuthenticationException" occurred in System.dll 
Certificate error: RemoteCertificateChainErrors 
Exception: The remote certificate is invalid according to the validation procedure. 
Authentication failed - closing the connection. 

Я знаю, что проблема может быть в том, что я использую разные типы сертификатов, но я не знаю, как создать стандартный sslServerSocket с X509Certificate в java. Может ли кто-нибудь помочь мне с хорошим примером или каким-то советом, как я могу достичь своей цели?

P.S. Я искал библиотеку bouncycastle, потому что у нее есть как java, так и реализация C#, но я бы хотел использовать стандартные библиотеки и встроенную функциональность языков.

+2

Ах, [воспоминания] (http://stackoverflow.com/questions/719556/c-sharp-client-connecting-to-a-java-server-over-ssl). (Один из моих первых вопросов на SO) –

+0

Это похоже на другой вопрос в StackOverflow, однако я не могу оставлять комментарии Вопрос: [x509 Создание сертификата без BouncyCastle] (http://stackoverflow.com/questions/1615871/create-a-x509-certificate-in-java-without-bouncycastle) И вот ссылка, найденная на странице, где описано, как это сделать: [Создание сертификата x509 в Java] (http://bfo.com/ Блог/2011/03/08/odds_and_ends_creating_a_new_x_509_certificate.html) – ry8806

+0

спасибо, это действительно помогло мне сгенерировать сертификат X509, но как я могу теперь связать это с SSLServerSocket в java? – savionok

ответ

2

В вашем примере это не похоже, что вам необходимо сгенерировать ваш сертификат и секретный ключ программно. Вы можете сгенерировать сертификат на сервере хранилище с keytool:

keytool -genkey -alias myalias -keystore mykeystore.jks -dname "CN=www.example.com" 

или лучше, с расширением SAN тоже, если вы используете Java 7-х keytool:

keytool -genkey -alias myalias -keystore mykeystore.jks -dname "CN=www.example.com" -ext san=dns:www.example.com 

Здесь www.example.com является хозяином имя, которое видит клиент. Вы можете добавить другие предметы в DN темы (dname), но убедитесь, что имя хоста CN.

После того, как он создан, экспортировать самозаверяющий сертификат с помощью:

keytool -export myservercert.crt -alias myalias -keystore mykeystore.jks 

Затем вы должны быть в состоянии импортировать его в качестве доверенного сертификата в вашем хранилище сертификатов Windows, от использования из C#.

+0

Зачем вам когда-либо создавать программный ключ сертификата? Кто бы этому поверил? – EJP

+0

@EJP согласился, это не очень полезно. Это может быть удобно, если вы пишете «прокси-сервер MITM» (например, Fiddler или [Squid's SslBump] (http://wiki.squid-cache.org/Features/SslBump)), где вы импортируете сертификат CA прокси в свой браузер, но генерировать новый сертификат «на лету» для запрашиваемого хоста. – Bruno

+0

спасибо! экспортируя jks в crt и импортируя этот crt в ОС, так как доверенный сертификат решил мою проблему! – savionok

Смежные вопросы