2012-03-06 17 views
5

Moim celem jest zapewnienie bezpiecznej komunikacji między serwerem Java a klientem napisanym w języku C#.Komunikacja SSL między aplikacjami Java i C#

java kod serwera:

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(); 
     } 
    } 

i klient napisany w 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"));  

i

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; 
    } 

i uzyskać następujące błędy: w 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. 

Wiem, że problem może polegać na tym, że używam różnych typów certyfikatów, ale nie wiem, jak utworzyć standardowy plik sslServerSocket z certyfikatem X509 w języku Java. Czy ktoś może mi pomóc, z dobrym przykładem, lub poradą, w jaki sposób mogę osiągnąć mój cel?

P.S. Szukałem biblioteki bouncycastle, powoduje, że ma ona zarówno java, jak i implementację C#, ale chciałbym użyć standardowych bibliotek i wbudowanej funkcjonalności języków.

+2

Ah, [wspomnienia] (http://stackoverflow.com/questions/719556/c-sharp-client-connecting-to-a-java-server-over-ssl). (Jedno z moich pierwszych pytań na temat SO) –

+0

To jest podobne do innego pytania na StackOverflow, jednak nie mogę zamieszczać komentarzy Pytanie: [x509 Tworzenie certyfikatu bez BouncyCastle] (http://stackoverflow.com/questions/1615871/creation-an-x509-certificate-in-java-without-bouncycastle) Tutaj znajduje się link znajdujący się na stronie opisującej, jak to zrobić: [Tworzenie certyfikatu x509 w Javie] (http://bfo.com/ blog/2011/03/08/odds_and_ends_creating_a_new_x_509_certificate.html) – ry8806

+0

dziękuję, to naprawdę pomogło mi wygenerować certyfikat X509, ale jak mogę teraz dołączyć to do SSLServerSocket w java? – savionok

Odpowiedz

2

Z twojego przykładu nie wygląda na to, że programowo trzeba wygenerować certyfikat i klucz prywatny. Można wygenerować certyfikat w swoim kluczy serwera z keytool:

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

lub lepiej z rozszerzeniem SAN też, jeśli używasz Java 7 na keytool:

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

Tutaj www.example.com jest gospodarzem nazwa widziana przez klienta. Możesz dodać inne rzeczy w temacie DN (dname), ale upewnij się, że nazwa hosta to CN.

Po jej wygenerowaniu wyeksportować certyfikat z podpisem własnym, używając:

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

Następnie powinno być w stanie importować go jako zaufanego certyfikatu w magazynie certyfikatów Windows z użycia z C#.

+0

Dlaczego musiałbyś programowo generować klucz prywatny certyfikatu? Kto by mu zaufał? – EJP

+0

@EJP zgodził się, nie jest to zbyt użyteczne. Może to być przydatne, jeśli napiszesz "proxy MITM" (jak Fiddler lub [Squid's SslBump] (http://wiki.squid-cache.org/Features/SslBump)), w którym zaimportujesz certyfikat CA proxy do przeglądarki, ale wygeneruj nowy certyfikat na bieżąco dla żądanego hosta. – Bruno

+0

dziękuję! eksportowanie jks do crt, a importowanie tego crt w systemie operacyjnym jako certyfikacie zaufanym rozwiązało mój problem! – savionok

Powiązane problemy