title: Extremely slow built-in AES encryption with Java
body: <p>I have a lot of very small data (19 Bytes) that need to be encrypted and sent
  to a remote server via tcp in encrypted format. I am using the code below to
  do this.</p>
  
  <pre><code>package aesclient;
  
  import java.io.OutputStream;
  import java.net.Socket;
  
  import java.security.SecureRandom;
  import javax.crypto.Cipher;
  import javax.crypto.spec.IvParameterSpec;
  import javax.crypto.spec.SecretKeySpec;
  
  public class AESClient {
      static byte[] plaintext = new byte[] {0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x50, 0x51, 0x52, 0x53};
      public static void main(String[] args) {
          try {
              Socket socket = new Socket("127.0.0.1", 1337); // connecting to server on localhost
              OutputStream outputStream = socket.getOutputStream();
              Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5PADDING");
              String s_key = "Random09" + "Random09"; // 16 Byte = 128 Bit Key
              byte[] b_key = s_key.getBytes();
              SecretKeySpec sKeySpec = new SecretKeySpec(b_key, "AES");
              SecureRandom random = SecureRandom.getInstanceStrong();
              byte[] IV = new byte[16]; // initialization vector
              int num = 10000;
              long start = System.nanoTime();
              for (int i = 0; i &lt; num; ++i) {
                  random.nextBytes(IV);
                  IvParameterSpec ivSpec = new IvParameterSpec(IV);
                  cipher.init(Cipher.ENCRYPT_MODE, sKeySpec, ivSpec);
                  byte[] msg = new byte[16 + 32];
                  System.arraycopy(IV, 0, msg, 0, IV.length);
                  byte[] encrypted = cipher.doFinal(plaintext);
                  System.arraycopy(encrypted, 0, msg, IV.length, encrypted.length);
                  outputStream.write(msg);
                  outputStream.flush();      
              }
              long end = System.nanoTime();
              long duration = end - start;
              double drate = ((double)plaintext.length*(double)num)/((double)duration/1000000000);
              System.out.println("Verschlüsselung:\n" + num + " mal 19 Bytes in " + ((double)duration/1000000000) + " s\nData Rate = " + drate/1000.0 + " kBytes/s");
          }
          catch (Exception e) {
              System.err.println(e.getMessage());
          }
      } 
  }
  </code></pre>
  
  <p>I am wondering why it is extremely slow. I get an output like this:</p>
  
  <pre><code>Verschlüsselung:
  10000 mal 19 Bytes in 2.566016627 s
  Data Rate = 74.04472675694785 kBytes/s
  </code></pre>
  
  <p>which means I have a data rate of 74 kByte/s of the original (unencrypted)
  data. The data rate only increases negligibly if I omit sending over TCP
  (then it's about 100kByte/s). I have read about data rates that are around
  20MByte/s or even higher. I have a laptop with Windows 10 and i5 processor.
  I would be grateful for any help. As I said, I just need to transfer a lot
  of small data packets (19 Byte) encrypted.</p>