views:

57

answers:

3

Hello, Is there simply way to dinamic generate untrusted ssl certificate without domain and applay it to server socket - all from code, no commandline or additional files?

Purpose is secure connection between two hosts witch know only IP and port to communicate each other - certificates generated randomly at server start and used as "untrusted", no domain so no verification (if I'm not wrong). I think this can be usefull in secureing data transfer between datacenters in third party apps.

This is working code for not encrypted simply client-server test.

package study.benchmark.utils;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import javax.net.ServerSocketFactory;
import javax.net.SocketFactory;
import org.junit.Test;

public class DynamicSSLTest {

    @Test
    public void sslServerSocketTest() throws Exception {

        System.out.println("ssl server test");

        final int port = 8750;

        // server

        Thread th = new Thread() {

            @Override
            public void run() {

                try {
                    //ServerSocketFactory factory = SSLServerSocketFactory.getDefault();
                    ServerSocketFactory factory = ServerSocketFactory.getDefault();

                    ServerSocket server = factory.createServerSocket(port);
                    Socket socket = server.accept();

                    OutputStream out = socket.getOutputStream();
                    out.write("some data".getBytes());

                    socket.close();

                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        };

        th.start();

        //client

        //SocketFactory factory =  SSLSocketFactory.getDefault();
        SocketFactory factory = SocketFactory.getDefault();

        Socket socket = factory.createSocket("localhost", port);
        InputStream is = socket.getInputStream();

        StringBuffer sb = new StringBuffer();

        int data;
        while ((data = is.read()) >= 0) {
            System.out.print((char) data);
        }

        System.out.println();

        socket.close();

        th.join();
    }

}
A: 

Why? It's not secure, and who will trust it anyway? Why can't you create a server certificate per deployment offline?

EJP
It is for secure data with self signed certificates, as far as I know apps can generate it dynamicly
inquisitor
No they can't. The client has to trust the server's certificate. In Java that means importing it into the client's truststore.
EJP
+1  A: 

For your stated purpose of securing communications between two hosts, both of which are under your control, SSH would be a better solution. You can generate a key pair shared only with your other machine. Google "java ssh" for a host of options.

verisimilidude
+1  A: 

You can generate a self-signed certificate dynamically using a library such as BouncyCastle (essentially, for the certificate to be self-signed, you using the same issuer DN as the subject DN and you sign with the private key corresponding to the certificate's public key). Then, you'll need to put it in a KeyStore (in memory at least, not necessarily on file) and build an SSLContext from it, so as to be able to build an SSLSocketFactory.

This can be useful for testing, but this will not make your application secure. Generally speaking, encryption without authentication of the remote party isn't secure. You can exchange information as "secretly" as you want with a remote party, but if you haven't verified its identity you're not really sure your secrets are given to the intended recipient.

If your certificate is generated dynamically, you would need to find a way for the client to know it's indeed the legitimate certificate, before making any calls to that server.

The general SSH approach (where one assumes few people actually check the fingerprint they get in the first connection -- some people actually do check out of band) is a compromise whereby clients tend to accept the key (more or less blindly) the first time but will be warned if it has changed. You could implement this sort of approach for handling X.509 certificate trust too, but if you re-generate a new self-signed certificate every time you restart your server, you're back to the initial problem.

You could address this problem by having some sort of online/dynamic CA, where the servers would request and be issued a certificate dynamically based on something they could prove to that CA dynamically (to prove they're one of your servers, perhaps based on some configuration parameter known by both), and then have the client trust that CA, but that's a more complex scenario.

Bruno