5

My goal is to make a secure communication between a Java server and client written in C#.

java server code:

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

and client written 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"));     

and

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

and i get the following errors: 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.

I know that the issue can be the fact that i use different types of certificates, but i don't know how to make a standard sslServerSocket with X509Certificate in java. Can some one help me, with good example, or some advice how can i reach my goal ?

P.S. I was looking to bouncycastle library, causes it has both java, and c# implementation, but i would like to use standard libraries, and built-in functionality of the languages.

savionok
  • 485
  • 4
  • 11
  • 2
    Ah, [memories](http://stackoverflow.com/questions/719556/c-sharp-client-connecting-to-a-java-server-over-ssl). (One of my first questions on SO) – Scott Chamberlain Mar 06 '12 at 20:12
  • This is kind of similar to another question on StackOverflow, however I can't post comments Question: [x509 Creating a certificate without BouncyCastle](http://stackoverflow.com/questions/1615871/creating-an-x509-certificate-in-java-without-bouncycastle) And here is a link found on the page which describes how to do it:[Creating an x509 Certificate in Java](http://bfo.com/blog/2011/03/08/odds_and_ends_creating_a_new_x_509_certificate.html) – ry8806 Mar 06 '12 at 16:40
  • thanks, this really helped me to generate X509 Certificate, but how can i now bundle this to SSLServerSocket in java ? – savionok Mar 06 '12 at 17:10
  • @ry8806, I'm not sure how this helps here, since there doesn't seem any requirement for generating a certificate within the application itself. Using a tool (e.g. `keytool`) should be much easier. – Bruno Mar 06 '12 at 20:06
  • @savionok i think this link might help you combining the x509 with the SSLServerSocket, its a small code example but it should help you on your way [link](http://www.java2s.com/Tutorial/Java/0490__Security/HTTPSServerAuthentication.htm) – ry8806 Mar 07 '12 at 10:26
  • Actually I want to do this the other way around. C# server with an android client. How can I create the self signed ssl certificates for both the C# server and the android client? Any help would be appreciated. – Mr.Noob Feb 20 '15 at 10:17

1 Answers1

2

From your example, it doesn't look like you need to generate your certificate and private key programmatically. You can generate a certificate in your server keystore with keytool:

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

Or better, with the SAN extension too, if you're using Java 7's keytool:

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

Here, www.example.com is the host name as seen by the client. You can add other things in the Subject DN (dname), but make sure the CN is the host name.

Once it's generated, export your self-signed certificate using:

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

You should then be able to import it as a trusted certificate in your Windows certificate store from use from C#.

Bruno
  • 119,590
  • 31
  • 270
  • 376
  • Why would you ever need to generate your certificate private key programmatically? Who would trust it? – user207421 Mar 07 '12 at 01:14
  • @EJP agreed, it's not of much use. It could be handy if you write a "MITM proxy" (like Fiddler or [Squid's SslBump](http://wiki.squid-cache.org/Features/SslBump)) where you would import the proxy's CA cert into your browser but generate a new cert on the fly for the requested host. – Bruno Mar 07 '12 at 10:45
  • thank you ! exporting jks to crt, and importing this crt in OS as a Trusted Certificate solved my problem ! – savionok Mar 07 '12 at 11:54