2012-03-06 22 views
5

Amacım, bir Java sunucusu ile C# 'da yazılan istemci arasında güvenli bir iletişim kurmaktır.Java ve C# uygulamaları arasında SSL iletişimi

java sunucu kodu: C# ile yazılmış

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

ve istemci:

 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"));  

ve

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

ve ben şu hataları alıyorum: 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. 

Bu sorunun farklı türde sertifikalar kullanabileceğimi biliyorum, ancak java'da X509Certificate ile standart bir sslServerSocket nasıl yapılacağını bilmiyorum. Bazıları bana iyi örneklerle veya bazı tavsiyelerde yardımcı olabilir mi? Hedefe nasıl ulaşabilirim?

P.S. Bouncycastle kütüphanesine bakıyordum, hem java'ya hem de C# uygulamasına sahip olmasına neden oluyor, ancak standart kütüphaneleri ve dillerin yerleşik işlevselliğini kullanmak istiyorum.

+2

Ah, [anılar] (http://stackoverflow.com/questions/719556/c-sharp-client-connecting-to-a-java-server-over-ssl). (SO'mdaki ilk sorularımdan biri) –

+0

Bu, StackOverflow ile ilgili başka bir soruya benzer, ancak yorum gönderemiyorum Soru: [x509 BouncyCastle olmadan sertifika oluşturma] (http://stackoverflow.com/questions/1615871/oluşturma-an-x509-sertifika-in-java-bouncycastle olmadan) Ve burada nasıl yapılacağını açıklayan sayfada bir bağlantı olduğunu: [Java x509 Sertifikası oluşturma] (http://bfo.com/ blog/2011/03/08/odds_and_ends_creating_a_new_x_509_certificate.html) – ry8806

+0

teşekkürler, bu gerçekten X509 Sertifikasını oluşturmama yardımcı oldu, ancak şimdi bunu JavaServerSocket'a java'da nasıl paketleyebilirim? – savionok

cevap

2

Örneğinizden, sertifikanızı ve özel anahtarınızı programsal olarak oluşturmanız gerekiyor gibi görünmüyor. Java 7 en keytool kullanıyorsanız, çok

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

Hatta, SAN uzantılı: Burada

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

, www.example.com ev sahipliği yapmaktadır Sen keytool ile sunucu deposundaki bir sertifika oluşturabilir müşteri tarafından görüldüğü adı. Konu DN'ye (dname) başka şeyler ekleyebilirsiniz, ancak CN'un ana bilgisayar adı olduğundan emin olun.

o Oluşturulan sonra kullanarak kendinden imzalı sertifikayı dışa:

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

Daha sonra C# kullanımından Windows sertifika deposunda güvenilen sertifikası almak gerekir.

+0

Neden sertifika özel anahtarınızı programlı olarak oluşturmanız gerekir? Kim buna güvenirdi? – EJP

+0

@EJP, çok fazla kullanımda bulunmadı. Proxy'nin CA sertifikasını tarayıcınıza aktaracağınız bir "MITM proxy" (Fiddler veya [Squid's SslBump] (http://wiki.squid-cache.org/Features/SslBump) gibi) yazabilirseniz kullanışlı olabilir. İstenen ana bilgisayar için anında yeni bir sertifika oluştur. – Bruno

+0

Teşekkürler! jks'yi crt'ye dışa aktarma ve bu crt'yi OS'de bir Güvenilir Sertifika olarak içe aktarma sorunumu çözdü! – savionok