title: HTTPS on Raspberry Pie is too slow. What can I do about it? Which cipher should I choose?
body: <h1>The Problem</h1>
  
  <p>Uploading videos from my raspberry pie to YouTube using the YouTube Data Api v3 is too slow. The max rate I get is 120 KB/s. I want to be able to archieve rates up to 1MB/s.</p>
  
  <h1>Why I believe SSL is the problem</h1>
  
  <p>To Upload Videos to YouTube I used to run a small java program which I could run on a Raspberry Pie over night to save power. It is connected to the YouTube Data API v2. I have three internet connections and the fastest is a LTE mobile connection. With that one <strong>my old app can upload with 1 Megabyte/second</strong> (and it does so very reliable up until the moment my 30GB included data is used up, which is why I use it in urgent cases only).</p>
  
  <p>Now I have created a successor for my app, which uses the API v3. In contrast to the v2 API uploads now also use HTTPS connections. However now I cannot upload any faster than 120 KB/s.</p>
  
  <p>Many hours of frustrated debugging later, I believe that the problem is due to the CPU load created by SSL. To verify this I started an enterprise grade <em>caugh</em> HTTPS Sever on my computer (connected to the raspberry pie via ethernet):</p>
  
  <pre class="lang-bash prettyprint-override"><code># create a self signed certificate (answer all the question it asks with default)
  openssl req -x509 -newkey rsa:2048 -keyout key.pem -out cert.pem -days 100 -nodes
  # Run the server on port 5454:
  openssl s_server -accept 5454 -key key.pem -cert cert.pem &gt; /dev/null
  </code></pre>
  
  <p>I assembled a small Java program which uses Apache HttpClient 4.3 (just like my app does) and performed a video "upload":</p>
  
  <pre class="lang-java prettyprint-override"><code>    final ProgressReportingHttpEntity entity = new ProgressReportingHttpEntity(new FileEntity(SOME_VIDEO_FILE, ContentType.APPLICATION_OCTET_STREAM));
      request.setEntity(entity);
      HttpClientBuilder
          .create()
          .setSSLSocketFactory(
              new SSLConnectionSocketFactory(
                      new SSLContextBuilder()
                          .loadTrustMaterial(null, new TrustSelfSignedStrategy())
                          .build(),
                      new AllowAllHostnameVerifier()
              )
          )
          .build().execute(request);
  </code></pre>
  
  <p>My laptop can transmit to itself 60MB/s (12% CPU go to Java (one core of my i7), 8% go to OpenSSL) using this setup.</p>
  
  <p>The raspberry pie can still transmit 1MB/s (which would be fast enough). However as far as I understand <a href="https://www.ssllabs.com/ssltest/analyze.html?d=www.googleapis.com&amp;s=74.125.239.52" rel="nofollow">this page here</a>, the googleapis-Server will prefer the cipher <code>TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256</code>. Thus I restarted my local server like this:</p>
  
  <pre class="lang-bash prettyprint-override"><code>openssl s_server -accept 5454 -key key.pem -cert cert.pem -cipher ECDHE-RSA-AES128-GCM-SHA256 &gt; /dev/null
  </code></pre>
  
  <p>And BINGO! I will not get any better transmission rates than 120KB/s.</p>
  
  <p>I tried around with different ciphers, setting the supported ciphers explicitly in the apache HTTP client and e.g. the cipher <code>TLS_DHE_RSA_WITH_AES_128_CBC_SHA</code> did very well, going up to 1,3MB/s.</p>
  
  <h1>The question</h1>
  
  <p>What can I do about it? Which cipher would provide a decent balance between performance and security? After comparing supported cipher charts and blindly guessing I thought that <code>TLS_DHE_RSA_WITH_AES_128_CBC_SHA</code> might be a good choice and would be supported by google. But actually it looks like it is not (setting this cipher in apache http client enables communication with my test server, but breaks with google).</p>
  
  <p>Or is there anything else I could do to speed up SSL throughput? E.g. is there an ARM optimized SSL library that I can somehow inject into the JRE (in case the Java 8 ARM JRE does not already contain such a thing)?</p>