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
[email protected]
https://lists.mozilla.org/listinfo/dev-tech-crypto