I'm trying to do AES GCM TLS 1.2 in Java using NSS. It works but it's very slow. My setup:
- Intel(R) Core(TM) i5-3210M CPU @ 2.50GHz - Ubuntu 13.10 64 bit - Library NSS 3.15.4 - Java(TM) SE Runtime Environment (build 1.8.0-ea-b121) I've configured the jre/lib/security/java.security file: ... security.provider.1=sun.security.pkcs11.SunPKCS11 ${java.home}/lib/security/nss.cfg ... This seems to be working. I see that doing AES encryption on a buffer is substantially faster than before. The real thing I'm interested in is doing TLS AES GCM. So I've written a client and a server that transfer some data. This is extremely slow. I end up transferring at a rate around 3 MB/s. I wrote the equivalent in pure C (using OpenSSL) and I can transfer data at a rate around 750 MB/s. So I'm a bit at a loss. Is this expected or not? My test programs for AES GCM consist of the following 3 files: A client, a server and a shared helper file. //////////////////////////////////////////////////////////////////////////////////////////// package aesecho; import javax.net.ssl.*; import java.io.*; public class Client { public static void main(String[] arstring) throws IOException { SSLSocketFactory sslsocketfactory = (SSLSocketFactory) SSLSocketFactory.getDefault(); SSLSocket sslsocket = (SSLSocket) sslsocketfactory.createSocket("localhost", 9999); sslsocket.setEnabledProtocols(new String[]{"TLSv1.2"}); Helper.selectCipherSuites(sslsocket); long startTime = System.nanoTime(); try (OutputStream outputstream = sslsocket.getOutputStream()) { final SSLSession session = sslsocket.getSession(); System.out.println("Chosen cipher suite: " + session.getCipherSuite()); byte[] buffer = new byte[Helper.BUF_SIZE]; for (int loop = 0; loop < Helper.LOOP_COUNT; ++loop) { outputstream.write(buffer); outputstream.flush(); } } long stopTime = System.nanoTime(); double totalTime = (stopTime - startTime) / 1e9; double mibs = Helper.BUF_SIZE * Helper.LOOP_COUNT / Helper.MIB; double bandwidth = mibs / totalTime; System.out.println("Bandwidth: " + bandwidth + " MiB/s"); } } //////////////////////////////////////////////////////////////////////////////////////////// package aesecho; import javax.net.ssl.*; import java.io.*; public class Server { public static void main(String[] arstring) throws IOException { SSLServerSocketFactory sslserversocketfactory = (SSLServerSocketFactory) SSLServerSocketFactory.getDefault(); SSLServerSocket sslserversocket = (SSLServerSocket) sslserversocketfactory.createServerSocket(9999); sslserversocket.setEnabledProtocols(new String[]{"TLSv1.2"}); try (SSLSocket sslsocket = (SSLSocket) sslserversocket.accept()) { byte[] buffer = new byte[Helper.BUF_SIZE]; for (int loop = 0; loop < Helper.LOOP_COUNT; ++loop) { int bytesToRead = Helper.BUF_SIZE; while (bytesToRead > 0) { InputStream inputstream = sslsocket.getInputStream(); int bytesRead = inputstream.read(buffer); bytesToRead -= bytesRead; } } } } } //////////////////////////////////////////////////////////////////////////////////////////// package aesecho; import java.util.*; import java.util.regex.*; import javax.net.ssl.SSLSocket; public class Helper { static final int LOOP_COUNT = 1; static final int MIB = 1024 * 1024; static final int BUF_SIZE = MIB * 10; static SSLSocket selectCipherSuites(SSLSocket socket) { String supportedCipherSuites[] = socket.getSupportedCipherSuites(); System.out.println("Supported cipher suites: " + Arrays.toString(supportedCipherSuites)); List<String> selectedCipherSuites = new ArrayList<>(); // String patternString = ".*"; String patternString = ".*AES.*128.*GCM.*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; } } -- dev-tech-crypto mailing list dev-tech-crypto@lists.mozilla.org https://lists.mozilla.org/listinfo/dev-tech-crypto