0

I read about the SSLSocket when i had already finished a Chat program with java that use normal ServerSocket. I am trying to replace the normal ServerSocket with SSlSocket, there is not much on the internet but i found something. Now my WhServer class look like this: This class is the one which start the Socket in a selected port, if you need to see other classes i will edit the question:

import java.io.IOException;
import java.net.*;
import javax.net.ServerSocketFactory;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocket;
import javax.net.ssl.SSLSocketFactory;

public class WhServer extends Thread {

  private int port;
  private ServerSocket server;
  private ChannelsManager manager;
  SSLContext context;
  SSLSocketFactory sslSf;

  public WhServer(int port, ChannelsManager manager) throws IOException {
    this.port = port;
    this.manager = manager;     
  }

  public void ServerStop() throws IOException{
      server.close();      
  }

  public WhServer(int port) throws IOException {
    this(port, new ChannelsManager());
  }

  public int getPort() {
    return port;
  }

  public void run() {
    try {
      while(true) {     
        ServerSocketFactory ssf = ServerSocketFactory.getDefault();
        server = ssf.createServerSocket(port);      
        Socket socket = server.accept();        
        sslSf = context.getSocketFactory();
        SSLSocket sslSocket = (SSLSocket) sslSf.createSocket(socket, null,socket.getPort(), false);
        sslSocket.setUseClientMode(false);      
        manager.initialite(socket);
      }
    } catch(Exception ex) {
        ex.printStackTrace();
    }
  }

}
Davide Rain
  • 63
  • 1
  • 3
  • 9
  • Looks like you have not initialised your SSLContext, it can only be null (unless initialised outside this class) – NickJ Jun 26 '14 at 08:56
  • No it isn't. My mistake, but how can i initialise it? What parameters i need? I am a beginner with sockets so if you can show me a little code example it would be perfect. (SSLContextSpi, Provider, String) what means each of those parameters? – Davide Rain Jun 26 '14 at 09:02
  • I'm afraid it's not an area I've any experience with, but a quick look at the API docs reveals some static getInstance() methods: http://docs.oracle.com/javase/7/docs/api/javax/net/ssl/SSLContext.html – NickJ Jun 26 '14 at 09:05
  • So i don't need to initialize it in that way? Here is the sample code that i take (http://stackoverflow.com/questions/6559859/is-it-possible-to-change-plain-socket-to-sslsocket) – Davide Rain Jun 26 '14 at 09:08
  • 1
    Not much on the Internet about this? Come off it. SO and the Oracle Java Forums are stuffed full of information about this. – user207421 Jun 26 '14 at 09:45
  • Yes but i have not found explicit examples concerning chats and I'm still not flexible with java. – Davide Rain Jun 26 '14 at 09:54

3 Answers3

1

context is null. nowhere in your code it is being initialized.

Here's a few static methods you can use to initialize it. http://docs.oracle.com/javase/7/docs/api/javax/net/ssl/SSLContext.html

static SSLContext getInstance(String protocol) Returns a SSLContext object that implements the specified secure socket protocol.

static SSLContext getInstance(String protocol, Provider provider) Returns a SSLContext object that implements the specified secure socket protocol.

static SSLContext getInstance(String protocol, String provider) Returns a SSLContext object that implements the specified secure socket protocol.

Some valid values for the protocol string are "SSL", "SSLv2", "SSLv3"...

So, first of all, if you intend to keep that "context" variable as a member variable, make it final and initialize it in your constructor like this:

public WhServer(int port, ChannelsManager manager) throws IOException {
    this.port = port;
    this.manager = manager;
    try {
        context = SSLContext.getInstance("SSL"); //pick the SSL protocol you need.
    } catch (Throwable t) { t.printStackTrace(); }

}
Gubatron
  • 6,222
  • 5
  • 35
  • 37
1

Firstly, your SSLContext context instance variable is never initialised, so it is null. Nothing specific to SSL or sockets here, it's just a basic Java error: if you try to call anything on this, it will throw an NPE.

Secondly, even if it's not null (for example, you can create a new instance with context = SSLContext.getInstance("TLS"), see SSLContext section of the Java Cryptography Architecture Standard Algorithm Name Documentation as indicated in the SSLContext API doc), you still need to initialise the SSLContext via its init method.

Since you're trying to implement a server, you'll need to provide a non-null keymanager, otherwise you'll get an SSLHandshakeException saying "no cipher suites in common". You can find details about this in this answer for example.

In addition, you don't need to use plain Sockets and upgrade them to SSLSockets after accepting like you do. It's not necessarily wrong, but the following might be easier:

 // Assuming you've initialised your SSLContext
  SSLServerSocketFactory sslSf = context.getServerSocketFactory();
  SSLServerSocket server = (SSLServerSocket) sslSf.createServerSocket(port);
  SSLServerSocketFactory ssf = ServerSocketFactory.getDefault();
  server = ssf.createServerSocket(port);      
  SSLSocket socket = (SSLSocket)server.accept();

Your socket coming from an SSLServerSocketFactory will already be in server mode. Of course, there's generally no need for the factories to be within the while loop.

Community
  • 1
  • 1
Bruno
  • 119,590
  • 31
  • 270
  • 376
  • This helped me to understand more thank you. Just one thing what is a keymanager? In the linked answer he use a remote keymanager, there is other way to implement a keymanager? – Davide Rain Jun 26 '14 at 11:18
  • You should follow up the link in that answer to [this other answer](http://stackoverflow.com/a/6341566/372643). – Bruno Jun 26 '14 at 11:23
  • I read that Java have a default keystore.How to use it without needing of external files? – Davide Rain Jun 26 '14 at 11:46
  • There's a default truststore, there's no default keystore. – Bruno Jun 26 '14 at 11:50
  • Sorry for my constant questions. I need Both of them Truststore and keystore isn't it? Because when i try to initialize the context via init i need those parameters (km, tm, random) or am I wrong? – Davide Rain Jun 26 '14 at 11:55
  • If you're just writing a server, without client-certificate authentication, you can use the default truststore and random (by passing `null`). – Bruno Jun 26 '14 at 12:11
  • Is it safe enough for a chat to do that? And if i want to use a keystore file can i put it inside the runnable .jar? Where i can read about how to make Ketstore files? p.s my objective is only to encrypt client-server communication – Davide Rain Jun 26 '14 at 12:17
  • Generally, you'd want the keystore to be configurable, not bundled with the code. It's more of a server administrator responsibility. You can use self-signed certificates, but it's often easier to get a certificate from a known CA (less trouble importing that cert into the trust stores of each client). – Bruno Jun 26 '14 at 12:20
0

First you need to create SSLContext with below code:

  KeyStore keyStore = KeyStore.getInstance("JKS");
  keyStore.load(new FileInputStream("test.jks"),"passphrase".toCharArray());

  // Create key manager
  KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance("SunX509");
  keyManagerFactory.init(keyStore, "passphrase".toCharArray());
  KeyManager[] km = keyManagerFactory.getKeyManagers();

  // Create trust manager
  TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance("SunX509");
  trustManagerFactory.init(keyStore);
  TrustManager[] tm = trustManagerFactory.getTrustManagers();

  // Initialize SSLContext
  SSLContext sslContext = SSLContext.getInstance("TLSv1");
  sslContext.init(km,  tm, null);

Replace the test.jks with your own keystore location.

To understand the SSL communication model in Java, you can refer to Java Secure Socket Extension (JSSE) Reference Guide.

A HTTPS client and HTTPS server demo in Java provides a quite demo on how to create SSL client and SSL server in Java.

PixelsTech
  • 3,229
  • 1
  • 33
  • 33