Hi,
We're attempting to migrate our server so it can utilize TLSv1.2 in Java 7 but we are having some difficulty getting it to work. I took the EchoServer/EchoClient example from http://stilius.net/java/java_ssl.php, I ran it and it worked fine (using default SSL). I modified the code to get an SSLContext and get the TLSv1.2 protocol:
SSLContext ret = SSLContext.getInstance("TLSv1.2");
ret.init(null, null, null);
This did not work, when the client sent data to the server we got an SSLHandShakeException. Through some searches it seemed as though I needed to use my own KeyStore instead of the default one that comes with Java, so I created one and modified the Echo tests to use that as the KeyStore (for the server) and the TrustStore (for the client).
Doing this worked as expected, when using the default ciphers. Now I modified the server and client to call 'setEnabledCiphers' passing it a TLSv1.2 cipher ("TLS_DHE_DSS_WITH_AES_128_CBC_SHA256" to be specific). The client can 'connect' but when I type something I get a handshake excepiton, the server shows
javax.net.ssl.SSLHandshakeException: no cipher suites in common
Here is the modified server code:
-----
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.security.KeyManagementException;
import java.security.KeyStore;
import java.security.NoSuchAlgorithmException;
import java.util.Arrays;
import javax.net.ssl.KeyManager;
import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLServerSocket;
import javax.net.ssl.SSLServerSocketFactory;
import javax.net.ssl.SSLSocket;
public class EchoServer {
private static KeyManager[] getKeyManagerArray(String keystore,
String keystorePasswd) {
KeyManager[] ret = null;
String keyFile = "mySrvKeystore";
if (null != keystore) {
keyFile = keystore;
} else {
keyFile = "mySrvKeystore";
File t = new File(keyFile);
if (!t.exists()) {
keyFile = "../" + keyFile;
t = new File(keyFile);
if (!t.exists()) {
throw new RuntimeException("Could not find key manager file");
}
}
}
if (null == keystorePasswd) {
keystorePasswd = "123456";
}
try {
System.out.println("Using keystore: " + keyFile);
KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");
KeyStore ks = KeyStore.getInstance("JKS");
// initialize KeyStore object using keystore name
ks.load(new FileInputStream(keyFile), null);
kmf.init(ks, keystorePasswd.toCharArray());
ret = kmf.getKeyManagers();
} catch (Exception e) {
e.printStackTrace();
}
return ret;
}
private static SSLContext getSSLContext() throws NoSuchAlgorithmException, KeyManagementException {
SSLContext ret = SSLContext.getInstance("TLSv1.2");
KeyManager[] km = getKeyManagerArray(null, null);
ret.init(km, null, null);
return ret;
}
public static void main(String[] arstring) {
try {
SSLContext sc = getSSLContext();
SSLServerSocketFactory sslserversocketfactory = (SSLServerSocketFactory) sc.getServerSocketFactory();
SSLServerSocket sslserversocket = (SSLServerSocket) sslserversocketfactory
.createServerSocket(9999);
final String[] enabledCipherSuites = { "TLS_DHE_DSS_WITH_AES_128_CBC_SHA256" };
sslserversocket.setEnabledCipherSuites(enabledCipherSuites);
System.out.println("Enabled ciphers: " + Arrays.toString(sslserversocket.getEnabledCipherSuites()));
SSLSocket sslsocket = (SSLSocket) sslserversocket.accept();
InputStream inputstream = sslsocket.getInputStream();
InputStreamReader inputstreamreader = new InputStreamReader(
inputstream);
BufferedReader bufferedreader = new BufferedReader(
inputstreamreader);
String string = null;
while ((string = bufferedreader.readLine()) != null) {
System.out.println(string);
System.out.flush();
}
} catch (Exception exception) {
exception.printStackTrace();
}
}
}
-----
Here is the updated client
-----
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.security.KeyManagementException;
import java.security.KeyStore;
import java.security.NoSuchAlgorithmException;
import java.util.Arrays;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocket;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;
import javax.net.ssl.TrustManagerFactory;
public class EchoClient {
private static TrustManager[] getTrustManagerArray(String truststore,
String pwd) {
TrustManager[] ret = null;
String trustFile = "mySrvKeystore";
if (null != truststore) {
trustFile = truststore;
} else {
File t = new File(trustFile);
if (!t.exists()) {
trustFile = "../" + trustFile;
t = new File(trustFile);
if (!t.exists()) {
throw new RuntimeException("Could not find trust file");
}
}
pwd = "123456";
}
try {
System.out.println("Using " + trustFile + " as truststore");
TrustManagerFactory tmf = TrustManagerFactory
.getInstance("SunX509");
KeyStore ts = KeyStore.getInstance("JKS");
// initialize truststore object using truststore name
ts.load(new FileInputStream(trustFile), pwd.toCharArray());
tmf.init(ts);
ret = tmf.getTrustManagers();
} catch (Exception e) {
e.printStackTrace();
}
return ret;
}
private static SSLContext getSSLContext() throws NoSuchAlgorithmException, KeyManagementException {
SSLContext ret = SSLContext.getInstance("TLSv1.2");
TrustManager[] tm = getTrustManagerArray(null, null);
ret.init(null, tm, null);
return ret;
}
public static void main(String[] arstring) {
try {
SSLContext sc = getSSLContext();
SSLSocketFactory sslsocketfactory = (SSLSocketFactory) sc.getSocketFactory();
SSLSocket sslsocket = (SSLSocket) sslsocketfactory.createSocket(
"localhost", 9999);
final String[] enabledCipherSuites = { "TLS_DHE_DSS_WITH_AES_128_CBC_SHA256" };
sslsocket.setEnabledCipherSuites(enabledCipherSuites);
System.out.println("Enabled ciphers: " + Arrays.toString(sslsocket.getEnabledCipherSuites()));
InputStream inputstream = System.in;
InputStreamReader inputstreamreader = new InputStreamReader(
inputstream);
BufferedReader bufferedreader = new BufferedReader(
inputstreamreader);
OutputStream outputstream = sslsocket.getOutputStream();
OutputStreamWriter outputstreamwriter = new OutputStreamWriter(
outputstream);
BufferedWriter bufferedwriter = new BufferedWriter(
outputstreamwriter);
String string = null;
while ((string = bufferedreader.readLine()) != null) {
bufferedwriter.write(string + '\n');
bufferedwriter.flush();
}
} catch (Exception exception) {
exception.printStackTrace();
}
}
}