Cant send ssl messages with java ssl socket
I am trying to create a server - client bundle that will let me send simple messages with ssl support. I am quite new at java and i can't figure out what my problem is. I am running the server and client programs at 2 computers at the same network and i can send messages. My problem is that when i capture the messages with wireshark the protocol is TCP and i can read the messages About the certificates now,i have create all my certificates with openssl and i have convert them to .jks with keytool. Myca.jks is the certificate of an selfsigned ca, i have signed the server and the client with this certificate. Thanks for any tip!
import java.io.*; import java.net.*; import java.security.*; import java.util.*; import javax.net.ssl.*; public class sslserver { ObjectOutputStream out; ObjectInputStream in; String message; sslserver(){} void run() throws Exception { char[] passphrase = "123456".toCharArray(); KeyStore keystore = KeyStore.getInstance("JKS"); keystore.load(new FileInputStream("/home/jimmysnn/JavaApplication4/src/keystore.jks"), passphrase); KeyStore serverkeystore = KeyStore.getInstance("JKS"); serverkeystore.load(new FileInputStream("/home/jimmysnn/JavaApplication4/src/server.jks"), passphrase); KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509"); kmf.init(keystore, passphrase); TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509"); tmf.init(serverkeystore); SSLContext context = SSLContext.getInstance("TLS"); TrustManager[] trustManagers = tmf.getTrustManagers(); KeyManager[] keyManagers = kmf.getKeyManagers(); context.init(keyManagers, trustManagers, null); //1. creating a server socket SSLServerSocketFactory ssf = context.getServerSocketFactory(); ServerSocket ss = ssf.createServerSocket(2004); //2. Wait for connection System.out.println("Waiting for connection"); Socket s = ss.accept(); System.out.println("Connection received from " + s.getInetAddress().getHostName()); //3. get Input and Output streams out = new ObjectOutputStream(s.getOutputStream()); out.flush(); in = new ObjectInputStream(s.getInputStream()); sendMessage("Connection successful"); //4. The two parts communicate via the input and output streams Scanner input = new Scanner( System.in ); do{ message = (String)in.readObject(); System.out.println("client>" + message); if (message.equals("bye")) sendMessage("bye"); }while(!message.equals("bye")); //4: Closing connection in.close(); out.close(); ss.close(); } void sendMessage(String msg) throws Exception { out.writeObject(msg); out.flush(); System.out.println("server>" + msg); } public static void main(String args[]) throws Exception { Server server = new Server(); while(true){ server.run(); } } }
import java.io.*; import java.net.*; import java.util.*; import java.security.*; import javax.net.ssl.*; public class sslclient { ObjectOutputStream out; ObjectInputStream in; String message; sslclient(){} void run() throws Exception { char[] passphrase = "123456".toCharArray(); KeyStore keystore = KeyStore.getInstance("JKS"); keystore.load(new FileInputStream("/home/ge0rge/Javaaskhsh4/src/myca.jks"), passphrase); KeyStore keystoreclient = KeyStore.getInstance("JKS"); keystoreclient.load(new FileInputStream("/home/ge0rge/Javaaskhsh4/src/client.jks"), passphrase); TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509"); tmf.init(keystore); KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509"); kmf.init(keystoreclient, passphrase); SSLContext context = SSLContext.getInstance("TLS"); TrustManager[] trustManagers = tmf.getTrustManagers(); KeyManager[] keyManagers = kmf.getKeyManagers(); context.init( keyManagers, trustManagers, null); SSLSocketFactory sf = context.getSocketFactory(); Socket s = sf.createSocket("192.168.1.5", 443); System.out.println("Connected to localhost in port 2004"); //2. get Input and Output streams out = new ObjectOutputStream(s.getOutputStream()); out.flush(); in = new ObjectInputStream(s.getInputStream()); //3: Communicating with the server Scanner input = new Scanner( System.in ); message = (String)in.readObject(); System.out.println("server>" + message); //message = input.nextLine(); sendMessage("Hi my server"); do{ message = input.nextLine(); sendMessage(message); if(message.equals("bye")){ message = (String)in.readObject(); System.out.println("server>" + message); } }while(!message.equals("bye")); in.close(); out.close(); s.close(); } void sendMessage(String msg) throws Exception { out.writeObject(msg); out.flush(); System.out.println("client>" + msg); } public static void main(String args[]) throws Exception { Client client = new Client(); client.run(); } }
You're using some non-standard terminology in your code, which may reflect some confusion in your implementation or indeed some mistakes.
The server needs a keystore, which contains his private key.
The client has a trustore, which contains certificates he is prepared to trust from other people, ie servers.
The server's cert needs to be exported from the server's keystore and imported into the client's truststore, unless it is signed by a CA, which is recommended and normal.
The server's keystore stays at the server; the client's truststore is at the client. So you don't need variable names like 'serverKeystore' etc. Just 'keystore' and 'truststore' as required.
You aren't using client auth so the client doesn't need a keystore and the server doesn't need a truststore.
I suggest you redo your code using these concepts, then it all might become clearer to everybody, especially you.
If it still doesn't work you must post the exception and stack trace. You may also need to run either your server or your client or both with -Djavax.net.debug=ssl,handshake
and post the results here.