Raspberry Pi上的HTTPS太慢了。我能做些什么呢?我应该选择哪种密码?

时间:2014-08-08 16:05:59

标签: java ssl youtube-api raspberry-pi apache-httpclient-4.x

问题

使用YouTube数据Api v3将视频从我的树莓派上传到YouTube太慢了。我得到的最大速率是120 KB / s。我希望能够达到高达1MB / s的速率。

为什么我认为SSL是问题

将视频上传到YouTube我曾经运行过一个小型的java程序,我可以在Raspberry Pie上运行一晚以节省电量。它与YouTube Data API v2相关联。我有三个互联网连接,最快的是LTE移动连接。有一个我的旧应用程序可以上传1兆字节/秒(并且它确实非常可靠,直到我的30GB包含的数据用完为止,这就是我在紧急情况下使用它的原因)

现在我已经为我的app创建了一个继承者,它使用了API v3。与v2 API上传相比,现在也使用HTTPS连接。但是现在我无法以超过120 KB / s的速度上传。

以后经过数小时的沮丧调试,我认为问题是由SSL产生的CPU负载造成的。为了验证这一点,我在计算机上启动了企业级 caugh HTTPS服务器(通过以太网连接到树莓派):

# 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 > /dev/null

我组装了一个小型Java程序,它使用Apache HttpClient 4.3(就像我的应用程序一样)并执行了一个视频"上传":

    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);

我的笔记本电脑可以使用此设置向自身传输60MB / s(12%CPU转到Java(我的i7的一个核心),8%转到OpenSSL)。

树莓派仍然可以传输1MB / s(这将足够快)。但据我了解this page here,googleapis-Server将更喜欢密码TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256。因此,我重新启动了我的本地服务器:

openssl s_server -accept 5454 -key key.pem -cert cert.pem -cipher ECDHE-RSA-AES128-GCM-SHA256 > /dev/null

BINGO!我的传输速率不会超过120KB / s。

我尝试使用不同的密码,在apache HTTP客户端中明确设置支持的密码,例如密码TLS_DHE_RSA_WITH_AES_128_CBC_SHA做得非常好,最高可达1,3MB / s。

问题

我该怎么办?哪种密码可以在性能和安全性之间提供适当的平衡?在比较支持的密码图表并盲目猜测后,我认为TLS_DHE_RSA_WITH_AES_128_CBC_SHA可能是一个不错的选择,并且会得到谷歌的支持。但实际上它看起来并非如此(在apache http客户端中设置此密码可以与我的测试服务器进行通信,但与谷歌打破)。

或者我还能做些什么来加快SSL吞吐量?例如。是否有一个ARM优化的SSL库,我可以以某种方式注入JRE(如果Java 8 ARM JRE还没有包含这样的东西)?

2 个答案:

答案 0 :(得分:1)

解决此问题的最快方法可能是完全避免SSL连接,而是使用YouTube的“通过EMAIL上传”选项通过SMTP上传视频......

https://support.google.com/youtube/answer/57407?hl=en

从YouTube设置页面获取用于上传视频的唯一电子邮件地址后,有很多方法可以实际从RaspberryPi发送电子邮件,并且您可以使用直接SMTP而不加密以获得最佳性能。

虽然您可能会担心由于base64编码而导致SMTP上传视频的效率太低,但似乎YouTube明智地通过RFC 3030支持8位编码。这是一个快速的TELNET测试,显示了他们支持的功能......

220 gmr-mx.google.com ESMTP hq8si1005325qcb.2 - gsmtp
EHLO josh.com
250-gmr-mx.google.com at your service, [108.29.37.132]
250-SIZE 35882577
250-8BITMIME
250-STARTTLS
250-ENHANCEDSTATUSCODES
250-PIPELINING
250-CHUNKING
250 SMTPUTF8

答案 1 :(得分:0)

你必须在某些时候误读某些东西。当您尝试使用密码TLS_DHE_RSA_WITH_AES_128_CBC_SHA时,您可能真的想尝试TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA(它们看起来确实相似)。

像这样初始化你的http客户端:

return HttpClientBuilder.create()
        .disableAutomaticRetries()
        .setSSLSocketFactory(
            new SSLConnectionSocketFactory(
                    new SSLContextBuilder().build(),
                    null,
                    new String[] { "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA" },
                    SSLConnectionSocketFactory.BROWSER_COMPATIBLE_HOSTNAME_VERIFIER
            )
        )
        .build();

根据我的测试,这将足够快,你的树莓派上传1MB / s。

不幸的是,我不是安全专家,我无法告诉您这个选择对您的安全意味着什么。如果你只支持一个密码,我也不知道你的应用程序有多么脆弱。