Rustls 有望超越 OpenSSL


Rustls 是一种用 Rust 编写的高质量 TLS 实现,旨在取代 OpenSSL 等不太安全的替代方案。本文探讨 Rustls 性能跟踪的最新进展,并提供 Rustls 0.22.0 和 OpenSSL 3.2.0(撰写本文时这两个项目的最新版本)之间的性能比较。

对基准测试的投资有助于确认 Rustls 与 OpenSSL 具有竞争力。在某些情况下,Rustls 已经更快,或者资源消耗更少。

除了正确性和安全性之外,TLS 实现将开销保持在最低限度也很重要。例如,考虑一下 Web 服务器负载较重的情况:高性能的 TLS 实现比性能较差的实现能够为更多的客户端提供服务。从历史上看,这导致业界将性能视为不可协商的特征,更喜欢具有低延迟和低资源占用的 TLS 实现,即使它们是用 C 等不安全语言编写的。

然而,随着 Rust 的兴起,在不影响性能的情况下,更安全的替代方案已经成为可能。2019 年,Joseph Birr-Pixton 的基准测试显示 Rustls 在数据传输吞吐量、每秒握手次数和内存使用量方面击败了 OpenSSL,这一点得到了证实。尽管 OpenSSL 的后续版本在一些基准测试中赶上了,但结果清楚地表明 Rustls 是一个值得关注的竞争者。

下面是通过比较 Rustls 0.22.0 和 OpenSSL 3.2.0 得出的最重要的结论:

  1. 当与aws-lc-rs加密提供程序(而不是ring)一起使用时,Rustls 可以实现最佳的整体性能。为了获得最高吞吐量,应该使用jemalloc分配器(与 Rust 的默认 glibc malloc 相比,它使传出数据传输的吞吐量增加了一倍以上)。由于这是性能最高的配置,我们在下面讨论进一步的结果时使用它。
  2. Rustls 使用的内存比 OpenSSL 少得多。在测试的工作负载中,高峰时 Rustls 会话的成本约为 13KiB,OpenSSL 会话的成本约为 69KiB。我们测得Rustls 的C10K内存使用量为 132MiB,OpenSSL 的 C10K 内存使用量为 688MiB。
  3. 当使用基于 AES 的密码套件时,Rustls 提供与 OpenSSL 大致相同的数据发送吞吐量。由于 Rustls API 中强制进行额外副本的限制,数据接收吞吐量降低了 7% 到 17%。我们正在努力消除该副本的必要性。
  4. 使用基于 ChaCha20 的密码套件时,Rustls 的数据传输吞吐量比 OpenSSL 低约 45%。进一步的研究表明,通过利用 AVX-512 支持,OpenSSL 的底层加密原语针对服务器级硬件进行了更好的优化(禁用 AVX-512 会导致 Rustls 和 OpenSSL 之间的性能相似)。奇怪的是,使用 Clang 编译的 OpenSSL 会降低到与禁用 AVX-512 时相同的吞吐量水平。
  5. Rustls 在服务器端每秒处理的完整 RSA 握手次数减少了 30% (TLS 1.2) 或 27% (TLS 1.3),但在客户端提供了显着更高的吞吐量(最多增加 106%,即 2.06 倍) )。这些差异可能是由于底层 RSA 实现造成的,因为使用 ECDSA 时情况正好相反(Rustls 在服务器端性能上大幅击败 OpenSSL,但在客户端性能上稍稍落后)。
  6. Rustls 每秒处理 80% 到 330%(取决于场景)更多的恢复握手,无论是使用会话 ID 还是基于票证的恢复。