After reading through numerous answers concerning these topics, I have found myself completely unable to string together the pieces of the puzzle, I hope you will excuse me for this.
I am trying to change my simple socket connection in Java to use SSL. I would like both the server and client to authenticate themselves if possible, but only server authentication would be good start.
Currently, this is the extremely simple code on the server side:
ServerSocket serverSocket = new ServerSocket(port);
Socket socket = serverSocket.accept();
And this is the code on the client side:
Socket socket = null;
while (true) {
try {
socket = new Socket(ipAddress, port);
break;
} catch (Exception e) {}
}
This works fine, but without SSL.
I have generated SSL certificates for the server and client using OpenSSL, ending up with:
- A certificate for the server (PEM format)
- A certificate for the client (PEM format)
- A private key for the server (PEM format)
- A private key for the client (PEM format)
- A CA file (PEM, CER and CRT format)
From this I have used OpenSSL to create PKCS12 (.p12) keystores for both the client and the server, as follows
- server.p12, made by doing openssl pkcs12 -export -in server-cert.pem -inkey server-private-key.pem -out server.p12
- client.p12, made by doing openssl pkcs12 -export -in client-cert.pem -inkey client-private-key.pem -out client.p12
Then, I turned these into JKS keystores by using keytool (for the server, for example, the command was keytool -importkeystore -srckeystore server.p12 -srcstoretype PKCS12 -destkeystore server.jks -deststoretype JKS), resulting in two files named server.jks and client.jks.
I then use the following code as replacement for the previous server snippet:
char[] keyStorePassword = "JKSPassword".toCharArray();
FileInputStream keyStoreFile = new FileInputStream("somepath/server.jks");
KeyStore keyStore = KeyStore.getInstance("JKS");
keyStore.load(keyStoreFile, keyStorePassword);
KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
keyManagerFactory.init(keyStore, "PKCS12Password".toCharArray());
SSLContext sslContext = SSLContext.getDefault();
ServerSocket serverSocket = sslContext.getServerSocketFactory().createServerSocket(port);
Socket socket = serverSocket.accept();
And the following code as replacement for the client snippet:
Socket socket = null;
while (true) {
try {
char[] keyStorePassword = "JKSPassword".toCharArray();
FileInputStream keyStoreFile = new FileInputStream("somepath/client.jks");
KeyStore keyStore = KeyStore.getInstance("JKS");
keyStore.load(keyStoreFile, keyStorePassword);
KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
keyManagerFactory.init(keyStore, "PKCS12Password".toCharArray());
SSLContext sslContext = SSLContext.getDefault();
socket = sslContext.getSocketFactory().createSocket(ipAddress, port);
break;
} catch (Exception e) {}
}
I now still get javax.net.ssl.SSLHandshakeException: no cipher suites in common on the server (and javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure on the client).
What could be wrong?