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

}
6
  • Looks like you have not initialised your SSLContext, it can only be null (unless initialised outside this class) Commented Jun 26, 2014 at 8: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? Commented Jun 26, 2014 at 9: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: docs.oracle.com/javase/7/docs/api/javax/net/ssl/SSLContext.html Commented Jun 26, 2014 at 9:05
  • So i don't need to initialize it in that way? Here is the sample code that i take (stackoverflow.com/questions/6559859/…) Commented Jun 26, 2014 at 9: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. Commented Jun 26, 2014 at 9:45

3 Answers 3

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.

Sign up to request clarification or add additional context in comments.

8 Comments

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?
You should follow up the link in that answer to this other answer.
I read that Java have a default keystore.How to use it without needing of external files?
There's a default truststore, there's no default keystore.
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?
|
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(); }

}

1 Comment

Correct. I also found this tutorial: gpotter2.github.io/tutos/en/sslsockets
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.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.