【问题标题】:HTTPS on Raspberry Pie is too slow. What can I do about it? Which cipher should I choose?树莓派上的 HTTPS 太慢了。我能做些什么呢?我应该选择哪种密码?
【发布时间】:2014-10-02 04:16:53
【问题描述】:

问题

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

为什么我认为 SSL 是问题所在

为了将视频上传到 YouTube,我曾经运行一个小型 Java 程序,我可以在 Raspberry Pie 上运行一整夜以节省电力。它连接到 YouTube 数据 API v2。我有三个互联网连接,最快的是 LTE 移动连接。有了那个我的旧应用程序可以以 1 兆字节/秒的速度上传(在我包含的 30GB 数据用完之前,它一直非常可靠,这就是为什么我只在紧急情况下使用它的原因) .

现在我已经为我的应用创建了一个后继者,它使用 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

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

    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

还有宾果游戏!我不会得到比 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 还没有包含这样的东西)?

【问题讨论】:

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


    【解决方案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
    

    【讨论】:

    • 我需要能够恢复使用 SMTP 无法完成的中断上传。另外附加的数据在 SMTP 中采用 base64 编码,因为 SMTP 是 7 位 ASCII 协议。这给数据增加了 33.33% 的开销,这是非常可观的。
    • 如果 SMTP 事务中断,您可以重试
    • > 这为数据增加了 33.33% 的开销,这是非常可观的:它不必如此。服务器支持8BITMIME
    • > 我需要能够恢复中断的上传:我认为这可以通过服务器支持 CHUNKING 来完成
    • @oleg:关于 8BITMIME 的要点。但是,据我了解,无法恢复中断的会话。此外,我的工具还设置了描述、标签、缩略图播放列表等。如果我使用 SMTP 上传,我需要以某种方式轮询我帐户中的现有视频并稍后添加元数据。此外,我的身份验证(我的秘密电子邮件地址)以我不喜欢的明文传输。然后 YouTube API v3 允许最大 64 GB 的视频文件。我找不到 SMTP 上传的限制。
    【解决方案2】:

    您一定在某些时候误读了某些内容。当您尝试使用密码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 的速度上传。

    很遗憾,我不是安全专家,我无法告诉您这种选择对您的安全意味着什么。另外,我不知道如果您只支持单一密码,它会使您的应用程序变得多么脆弱。

    【讨论】:

    • 谢谢,它有效!欢呼!关于你的考虑,也许其他人可以对这个选择说些什么。
    • 老兄……你是不是用第二人称回答了自己的问题,然后再回答自己?
    • TLS_DHE_RSA_WITH_AES_128_CBC_SHATLS_ECDHE_RSA_WITH_AES_128_CBC_SHA 使用相同的对称密码。完成密钥协商后,您应该不会看到速度差异(密钥协商是握手期间执行的 Diffie-Hellman 部分)。
    • @jww:重要的是 DHE 密码被 google 拒绝,而 ECDHE 没有。当我问我的问题时,我不小心使用了 DHE,并惊讶地发现它根本不起作用。
    • @JNYRanger:是的。我认为这使得阅读这里的问题/答案流程更容易理解。也更有趣。
    猜你喜欢
    • 1970-01-01
    • 2010-12-06
    • 1970-01-01
    • 2020-07-14
    • 2010-10-22
    • 2011-04-14
    • 2014-09-06
    • 2012-01-25
    • 1970-01-01
    相关资源
    最近更新 更多