2012-03-06 27 views
5

Il mio obiettivo è realizzare una comunicazione sicura tra un server Java e un client scritto in C#.Comunicazione SSL tra applicazioni Java e C#

codice server

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

e client scritto in 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"));  

e

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

e ottengo i seguenti errori: in 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. 

So che il problema può essere il fatto che utilizzo diversi tipi di certificati, ma non so come creare uno sslServerSocket standard con X509Certificate in java. Qualcuno può aiutarmi, con un buon esempio, o qualche consiglio, come posso raggiungere il mio obiettivo?

P.S. Stavo cercando la libreria bouncycastle, perché ha sia l'implementazione java che C#, ma mi piacerebbe usare le librerie standard e le funzionalità incorporate delle lingue.

+2

Ah, [memorie] (http://stackoverflow.com/questions/719556/c-sharp-client-connecting-to-a-java-server-over-ssl). (Una delle mie prime domande su SO) –

+0

Questo è simile ad un'altra domanda su StackOverflow, tuttavia non posso pubblicare commenti Domanda: [x509 Creare un certificato senza BouncyCastle] (http://stackoverflow.com/questions/1615871/creating-an-x509-certificate-in-java-without-bouncycastle) Ed ecco un collegamento trovato nella pagina che descrive come farlo: [Creazione di un certificato x509 in Java] (http://bfo.com/ blog/2011/03/08/odds_and_ends_creating_a_new_x_509_certificate.html) – ry8806

+0

grazie, questo mi ha davvero aiutato a generare il certificato X509, ma come posso ora associarlo a SSLServerSocket in java? – savionok

risposta

2

Dal tuo esempio, non sembra che sia necessario generare il certificato e la chiave privata a livello di programmazione. È possibile generare un certificato nel keystore server con keytool:

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

O meglio, con l'estensione SAN troppo, se si sta utilizzando Java 7 del keytool:

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

Qui, www.example.com è il padrone di casa nome come visto dal cliente. È possibile aggiungere altre informazioni nel DN oggetto (dname), ma assicurarsi che lo CN sia il nome host.

Una volta che è generato, esportare il certificato autofirmato utilizzando:

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

si dovrebbe quindi essere in grado di importarlo come certificato attendibile nell'archivio certificati di Windows da un uso da C#.

+0

Perché dovresti mai avere bisogno di generare la chiave privata del certificato a livello di programmazione? Chi si fiderebbe di esso? – EJP

+0

@EJP d'accordo, non è di grande utilità. Potrebbe essere utile se si scrive un "proxy MITM" (come Fiddler o [Squid's SslBump] (http://wiki.squid-cache.org/Features/SslBump)) dove si importerebbe il CA CA del proxy nel browser, ma generare un nuovo certificato al volo per l'host richiesto. – Bruno

+0

grazie! esportando jks in crt e importando questo crt in OS come Certificate Certificate ho risolto il mio problema! – savionok

Problemi correlati