I wrote a little test client/server setup that transfers 100 MB of data over an SSL socket configured to use TLS 1.2 AES GCM (TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256). On my i7-4770 CPU @ 3.40GHz with OpenJDK 1.8.0-ea-b124 I get a transfer rate of around 5.2 MiB/second. I expected a higher speed. Using TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 I reach 100 MiB/s. Is this to be expected?
For reference, here is my code: ///// Client.java package ssl; import javax.net.ssl.*; import java.io.*; import java.util.Arrays; public class Client { public static void main(String[] arstring) { try { SSLSocketFactory sslsocketfactory = (SSLSocketFactory) SSLSocketFactory.getDefault(); SSLSocket sslsocket = (SSLSocket) sslsocketfactory.createSocket("localhost", 9999); Helper.requireAESCipherSuites(sslsocket); sslsocket.setEnabledProtocols(new String[]{"TLSv1.2"}); try (OutputStream outputstream = sslsocket.getOutputStream()) { byte[] buf = new byte[Helper.BUF_SIZE]; Arrays.fill(buf, (byte) 1); for (int i = 0; i < Helper.BUF_COUNT; ++i) { outputstream.write(buf); } System.out.println("Using cipher suite: " + (sslsocket.getSession()).getCipherSuite()); outputstream.flush(); } } catch (IOException exception) { exception.printStackTrace(); } } } ///// Server.java package ssl; import javax.net.ssl.*; import java.io.*; public class Server { public static void main(String[] arstring) { try { SSLServerSocketFactory sslserversocketfactory = (SSLServerSocketFactory) SSLServerSocketFactory.getDefault(); SSLServerSocket sslserversocket = (SSLServerSocket) sslserversocketfactory.createServerSocket(9999); SSLSocket sslsocket = (SSLSocket) sslserversocket.accept(); InputStream inputstream = sslsocket.getInputStream(); byte[] buf = new byte[Helper.BUF_SIZE]; long bytesToRead = BYTES_TO_READ; long startTime = System.currentTimeMillis(); while (bytesToRead > 0) { bytesToRead -= inputstream.read(buf); } long stopTime = System.currentTimeMillis(); long totalTimeMs = stopTime - startTime; double mbRead = BYTES_TO_READ / (1024.0 * 1024); double totalTimeSeconds = totalTimeMs / 1000.0; double mibPerSecond = mbRead / totalTimeSeconds; System.out.println("Using cipher suite: " + (sslsocket.getSession()).getCipherSuite()); System.out.println("Read " + mbRead + "MiB in " + totalTimeSeconds + "s"); System.out.println("Bandwidth: " + mibPerSecond + "MiB/s"); } catch (IOException exception) { exception.printStackTrace(); } } private static final int BYTES_TO_READ = Helper.BUF_COUNT * Helper.BUF_SIZE; } ///// Helper.java package ssl; import java.util.*; import java.util.regex.*; import javax.net.ssl.*; public class Helper { static int BUF_SIZE = 1024 * 1024; static int BUF_COUNT = 100; static SSLSocket requireAESCipherSuites(SSLSocket socket) { String supportedCipherSuites[] = socket.getSupportedCipherSuites(); System.out.println("Supported cipher suite: " + Arrays.toString(supportedCipherSuites)); List<String> selectedCipherSuites = new ArrayList<>(); // String patternString = ".*"; String patternString = "TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256"; // String patternString = "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256"; Pattern pattern = Pattern.compile(patternString); for (String cipherSuite : supportedCipherSuites) { Matcher matcher = pattern.matcher(cipherSuite); if (matcher.find()) { selectedCipherSuites.add(cipherSuite); } } System.out.println("Selected cipher suites: " + selectedCipherSuites); socket.setEnabledCipherSuites(selectedCipherSuites.toArray(new String[0])); return socket; } }