PEP 644 – 要求 OpenSSL 1.1.1 或更高版本
- 作者:
- Christian Heimes <christian at python.org>
- 讨论至:
- Discourse 帖子
- 状态:
- 最终版
- 类型:
- 标准跟踪
- 创建日期:
- 2020年10月27日
- Python 版本:
- 3.10
- 发布历史:
- 2020年10月27日,2021年3月3日,2021年3月17日,2021年4月17日
- 决议:
- Python-Dev 消息
摘要
本PEP提议CPython的标准库只支持OpenSSL 1.1.1 LTS或更高版本。对已过生命周期、不兼容的fork以及其他TLS库的支持将被放弃。
动机
Python在 hashlib、 hmac 和 ssl 模块中使用了OpenSSL。OpenSSL提供了加密原语的快速实现以及一个完整的TLS堆栈,包括X.509证书的处理。ssl 模块被标准库模块(如 urllib)和第三方模块(如 urllib3)用于实现互联网协议的安全变体。pip 使用 ssl 模块从PyPI安全下载软件包。ssl 模块绑定OpenSSL的任何bug都可能导致严重的安全问题。
随着时间的推移,OpenSSL的公共API不断演变和变化。版本1.0.2引入了新的API来验证和匹配主机名。OpenSSL 1.1.0使内部结构不透明,并引入了新的API来取代对结构成员的直接访问。版本3.0.0将因内部重组而废弃更多API,这些重组将加密算法从核心移到提供者中。LibreSSL和BoringSSL等fork已经朝不同的方向发展。
目前,Python 3.6至3.9版本与OpenSSL 1.0.2、1.1.0和1.1.1兼容。在大多数情况下,Python也与LibreSSL >= 2.7.1兼容,但缺少一些功能和一些测试失败。
由于资源和时间有限,支持多个版本和分支,以及测试和验证正确性变得越来越困难。除了多个不兼容的API之外,还有构建时标志、特定于发行版的补丁以及本地加密策略设置,这些都增加了组合的复杂性。另一方面,Python核心团队只有少数熟悉TLS和OpenSSL内部的领域专家,而活跃的维护者更少。
要求使用 OpenSSL 1.1.1 将使我们能够为绝大多数用户提供更好的体验,减少我们的维护开销,从而释放资源来实施新功能。用户将能够依赖新功能的出现和一致的行为,最终带来更强大的体验。
影响
OpenSSL 1.1.1 是几乎所有受支持的平台和发行版上的 OpenSSL 默认变体和版本。它也是唯一仍受上游安全支持的版本 [9]。
macOS 和 Windows 用户不会受到此弃用的影响。python.org 安装程序和 Conda 等替代发行版均随附最新的 OpenSSL 版本。
截至2020年10月,根据DistroWatch [1],大多数当前的BSD和Linux发行版也随附OpenSSL 1.1.1。一些长期支持(LTS)和企业发行版的旧版本有较旧的OpenSSL或LibreSSL版本。到Python 3.10普遍可用时,其中一些发行版将达到生命周期结束、通用支持结束,或从LibreSSL转向OpenSSL。
其他软件也已放弃对 OpenSSL 1.0.2 的支持。例如,PyCA cryptography 3.2 (2020-10-25) 移除了与 OpenSSL 1.0.2 的兼容性。
OpenSSL 1.0.2 LTS
发布:2015-02 生命周期结束:2019-12
OpenSSL 1.0.2 添加了主机名验证、ALPN 支持和椭圆曲线。
- CentOS 7 (EOL 2024-06)
- Debian 8 Jessie (EOL 2020-07)
- Linux Mint 18.3 (EOL 2021-04)
- RHEL 7 (全面支持于 2019-08 结束,维护 2 支持于 2024-06 结束)
- SUSE Enterprise Linux 12-SP5 (通用支持于 2024-10 结束)
- Ubuntu 16.04 LTS / Xenial (通用支持于 2021-04 结束)
OpenSSL 1.1.0
发布:2016-08 生命周期结束:2019-09
OpenSSL 1.1.0 默认移除或禁用了不安全的密码,并增加了对 ChaCha20-Poly1305、BLAKE2 (基本功能)、X25519 和 CT 的支持。大多数结构变得不透明,并引入了新的 API。OpenSSL 1.1.0 与 1.0.2 不兼容 API。
- Debian 9 Stretch (安全支持于 2020-07 结束,LTS 直到 2022-06)
- Ubuntu 18.04 LTS / Bionic (通用支持于 2023-04 结束)
OpenSSL 1.1.1 LTS
发布:2018-08 生命周期结束:2023-09(计划)
OpenSSL 1.1.1 添加了 TLS 1.3、SHA-3、X448 和 Ed448。
- Alpine(2018年切换回OpenSSL [4])
- Arch Linux 当前
- CentOS 8.0+
- Debian 10 Buster
- Debian 11 Bullseye (预计于 2021-06 发布)
- Fedora 29+
- FreeBSD 11.3+
- Gentoo Linux 稳定版(于 2021 年 1 月停止将 LibreSSL 作为替代方案 [10])
- HardenedBSD(2018年切换回OpenSSL [3])
- Linux Mint 19.3+
- macOS (python.org 安装程序)
- NetBSD 8.2+
- openSUSE 15.2+
- RHEL 8.0+
- Slackware 当前
- SUSE Enterprise Linux 15-SP2
- Ubuntu 18.10+
- Ubuntu 20.04 LTS / Focal
- VoidLinux (于 2021 年 3 月切换回 OpenSSL [5])
- Windows (python.org 安装程序, Conda)
主要的 CI 提供商提供带有 OpenSSL 1.1.1 的镜像。
- AppVeyor(使用镜像
Ubuntu2004) - CircleCI(使用最新的
cimg/base:stable或cimg/base:stable-20.04) - GitHub Actions(使用
runs-on: ubuntu-20.04) - Giblab CI(使用 Debian Stretch, Ubuntu Focal, CentOS 8, RHEL 8, 或 Fedora runner)
- Packit
- TravisCI(使用
dist: focal) - Zuul
OpenSSL 3.0.0
发布:不适用(计划于 2021 年中/末)
OpenSSL 3.0.0 目前正在开发中。主要变化包括重新授权为 Apache License 2.0,以及为加密算法提供商提供新的 API。大多数变化是内部重构,不影响公共 API。[8]
LibreSSL
创建:2014-04(从 OpenSSL 1.0.1g 分支)
- DragonFly BSD
- Hyperbola GNU/Linux-libre
- OpenBSD
- OpenELEC(已停产)
- TrueOS(已停产)
一些发行版,如 FreeBSD 和 OPNsense,也采用 LibreSSL 而非 OpenSSL 作为非标准 TLS 库。Gentoo 于 2021 年 1 月停止将 LibreSSL 作为 OpenSSL 的替代品 [10],原因是兼容性问题和测试不足。
OpenBSD ports 有一个端口 security/openssl/1.1,其文档记载为“[…] 旨在为无法与 LibReSSL 兼容的应用程序提供支持” [7]。OpenBSD 可以使用该软件包来提供一个可用的 ssl 模块。
BoringSSL
创建时间:2014-06
BoringSSL 是 Google 的 OpenSSL 分支。它不打算用于一般用途,因此不受 Python 支持。无法保证 API 或 ABI 的稳定性。Chrome/Chromium 浏览器、Android 和 Apple 平台都使用了 BoringSSL 的打包副本 [6]。
好处
TLS 1.3
OpenSSL 1.1.1 引入了对新版 TLS 1.3 的支持。最新版本的 TLS 协议握手速度更快,并且比以前的版本更安全。
线程和fork安全
从 1.1.0c 版本开始,OpenSSL 完全支持 fork 和线程安全。绑定不再需要任何变通方法或额外的回调来支持多线程。
SHA-3
自 1.1.0 起,OpenSSL 附带 SHA-3 和 SHAKE 实现。Python 的内置 SHA-3 支持基于参考实现。内部 _sha3 代码相当大,生成的共享库接近 0.5 MB。Python 可以放弃内置实现,转而依赖 OpenSSL 的 libcrypto。
迄今为止,LibreSSL 上游开发拒绝添加 SHA-3 支持。[2]
兼容性
OpenSSL 下游补丁和选项
OpenSSL 提供了超过 70 个配置和构建时选项,形式为 OPENSSL_NO_* 宏。大约 60 个选项影响加密算法和 TLS 版本等功能的可用性。有些发行版会应用补丁来更改设置。此外,安全级别、密码、TLS 版本范围和签名算法等设置的默认值可以在 OpenSSL 配置文件中设置。
Python 核心团队缺乏测试所有可能组合的资源。本 PEP 建议 Python 仅支持启用标准功能的 OpenSSL 构建。供应商应使用构建时选项(如 OPENSSL_NO_TLS1_1_METHOD)或 OpenSSL 配置选项(如 MinProtocol = TLSv1.2)禁用已弃用或不安全的算法和 TLS 版本。
Python 假定 OpenSSL 的构建包含:
- hashlib 的默认算法,如 MD5、SHA-1、SHA-2 家族、SHA-3/SHAKE 家族、BLAKE2
- TLS 1.2 和 TLS 1.3 协议
- 用于 TLS 1.2 和 1.3 的当前密钥协商、签名和加密算法(ECDH、RSA、ECDSA、Curve25519、AES、Poly1309-ChaCha20 等)
- 线程、文件 I/O、套接字 I/O 和错误消息
弱算法(MD5、SHA-1 签名)和短密钥(RSA < 2024 位)可以在运行时禁用。算法也可能因加密策略(如 FIPS)禁用而被阻止。本 PEP 故意不更具体,以留出空间用于新功能以及应对漏洞的对策。通常来说,Python 应该能够连接到 PyPI,并且测试套件应该通过。
LibreSSL 支持
LibreSSL 是 OpenSSL 的一个分支。在 2014 年,OpenBSD 团队的成员针对 Heartbleed 漏洞从 OpenSSL 1.0.1g 创建了这个分支。自其成立以来,一些被认为有问题或不安全的功能被移除或替换(SSL 2.0、SSL 3.0、改进的 CPRNG)或从 OpenSSL 和 BoringSSL 反向移植。
目前,LibreSSL 与 OpenSSL 1.1.1 并非完全 API 兼容。最新版本 LibreSSL 3.3.2 缺少一些功能,并且在某些情况下行为有所不同。值得注意的缺失或不兼容功能包括
- SHA-3、SHAKE、BLAKE2
SSL_CERT_*环境变量- 安全级别 API
- 会话处理 API
- 密钥日志 API
- 已验证的证书链 API
- OPENSSL_VERSION 宏
本 PEP 提议从 Python 中移除所有与 LibreSSL 相关的变通方案。将来,Python 将不会通过配置和编译时检查主动禁止 LibreSSL 支持。但 Python 也不会接受添加非平凡变通方案或禁用测试的补丁。
BoringSSL
目前没有支持 BoringSSL 的计划。
被拒绝的想法
正式支持的 OpenSSL 版本
本 PEP 未提供一套正式的规则和条件来定义支持 OpenSSL 版本的标准。
通常,Python 旨在与常用且官方支持的 OpenSSL 版本兼容。Python 的补丁版本可能与 OpenSSL 的新主要版本不兼容。用户不应期望 Python 的新主要或次要版本能与已过生命周期的 OpenSSL 版本一起工作。Python 核心开发团队可能会为新版本向后移植修复或根据需要扩展与已达 EOL 版本的兼容性。
OpenSSL 的新 ABI 稳定性和 LTS 策略 [9] 也应该有所帮助。
保留对 OpenSSL 1.1.0 的支持
有人建议保留对 OpenSSL 1.1.0 的支持,以兼容 Debian 9 (Stretch)。该提议被驳回,因为它会使代码清理和测试复杂化。Stretch 已经超出常规安全支持,并接近长期支持的末尾。到 Python 3.10 最终发布时,Debian Buster 和 Debian Bullseye 将可用。
相反,Python 3.10 将增加额外的文档和一个新的 configure 选项 --with-openssl-rpath=auto,以简化自定义 OpenSSL 构建的使用 [11]。
向后兼容性
Python 3.10 将不再支持使用 OpenSSL 1.0.2 或 LibreSSL 的平台上的 TLS/SSL 和快速哈希。本 PEP 的初稿在 3.10 发布周期的开始发布,以便 Linux 发行版或 CI 提供商等供应商有足够的时间进行规划。
Python 内部的 Keccak Code Package 副本和内部的 _sha3 模块将被移除。这将使源代码大小减少约 280KB,代码大小减少约 0.5MB。hashlib 将完全依赖 OpenSSL 的 SHA-3 实现。没有 OpenSSL 将不再提供 SHA-3 和 SHAKE。
免责声明和特别感谢
本 PEP 的作者是 OpenSSL 项目的贡献者,受雇于一家使用 OpenSSL 的主要 Linux 发行商。
感谢 Alex Gaynor、Gregory P. Smith、Nathaniel J. Smith、Paul Kehrer 和 Seth Larson 对初稿的审阅和反馈。
参考资料
版权
本文档置于公共领域或 CC0-1.0-Universal 许可证下,以更宽松者为准。
来源:https://github.com/python/peps/blob/main/peps/pep-0644.rst