2012-03-06 30 views
5

Mi objetivo es establecer una comunicación segura entre un servidor Java y el cliente escrito en C#.Comunicación SSL entre aplicaciones Java y C#

código del servidor

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

y el cliente escrito en 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"));  

y

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

y consigo los siguientes errores: en 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. 

Sé que el problema puede ser el hecho de que utilizo diferentes tipos de certificados, pero no sé cómo hacer un sslServerSocket estándar con X509Certificate en java. ¿Puede alguien ayudarme, con un buen ejemplo o algún consejo, cómo puedo alcanzar mi objetivo?

P.S. Buscaba en la biblioteca de bouncycastle, hace que tenga implementaciones java y C#, pero me gustaría utilizar bibliotecas estándar y la funcionalidad integrada de los idiomas.

+2

Ah, [memorias] (http://stackoverflow.com/questions/719556/c-sharp-client-connecting-to-a-java-server-over-ssl). (Una de mis primeras preguntas sobre SO) –

+0

Esto es parecido a otra pregunta en StackOverflow, sin embargo no puedo publicar comentarios Pregunta: [x509 Creando un certificado sin BouncyCastle] (http://stackoverflow.com/questions/1615871/creating-an-x509-certificate-in-java-without-bouncycastle) Y aquí hay un enlace que se encuentra en la página que describe cómo hacerlo: [Creación de un certificado x509 en Java] (http://bfo.com/ blog/2011/03/08/odds_and_ends_creating_a_new_x_509_certificate.html) – ry8806

+0

gracias, esto realmente me ayudó a generar el Certificado X509, pero ¿cómo puedo ahora empaquetar esto en SSLServerSocket en Java? – savionok

Respuesta

2

Según su ejemplo, no parece que necesite generar su certificado y clave privada mediante programación. Puede generar un certificado en el almacén de claves del servidor con keytool:

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

O mejor, con la extensión SAN también, si está usando Java 7 de keytool:

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

Aquí, www.example.com es el anfitrión nombre visto por el cliente Puede agregar otras cosas en el DN Asunto (dname), pero asegúrese de que CN es el nombre de host.

Una vez que se genera, exportar su certificado autofirmado usando:

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

A continuación, debería ser capaz de importar como un certificado de confianza en el almacén de certificados de Windows del uso de C#.

+0

¿Por qué necesitarías generar tu clave privada de certificado programáticamente? ¿Quién lo confiaría? – EJP

+0

@EJP estuvo de acuerdo, no es de mucha utilidad. Podría ser útil si escribe un "proxy MITM" (como Fiddler o [Squid's SslBump] (http://wiki.squid-cache.org/Features/SslBump)) donde importaría el certificado de CA del proxy en su navegador, pero generar un nuevo certificado sobre la marcha para el host solicitado. – Bruno

+0

¡gracias! exportar jks a crt, e importar este crt en SO como certificado de confianza resolvió mi problema! – savionok

Cuestiones relacionadas