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 或更高版本。对 OpenSSL 生命周期结束后的版本、不兼容的分支以及其他 TLS 库的支持将被放弃。
动机
Python 在 hashlib
、hmac
和 ssl
模块中使用了 OpenSSL。OpenSSL 提供了加密原语的快速实现以及完整的 TLS 栈,包括 X.509 证书的处理。ssl
模块被标准库模块(如 urllib
)和第三方模块(如 urllib3
)用于实现互联网协议的安全变体。pip
使用 ssl
模块从 PyPI 安全地下载软件包。ssl
模块与 OpenSSL 的绑定中的任何错误都可能导致严重的安全性问题。
随着时间的推移,OpenSSL 的公共 API 已经发展和改变。1.0.2 版本引入了新的 API 来验证和匹配主机名。OpenSSL 1.1.0 使内部结构体不透明,并引入了新的 API 来替换对结构体成员的直接访问。3.0.0 版本将弃用更多 API,因为内部重组将加密算法从核心移至提供程序。LibreSSL 和 BoringSSL 等分支已向不同的方向发展。
目前,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 年 2 月 生命周期结束:2019 年 12 月
OpenSSL 1.0.2 添加了主机名验证、ALPN 支持和椭圆曲线。
- CentOS 7(EOL 2024 年 6 月)
- Debian 8 Jessie(EOL 2020 年 7 月)
- Linux Mint 18.3(EOL 2021 年 4 月)
- RHEL 7(完整支持结束于 2019 年 8 月,维护支持结束于 2024 年 6 月)
- SUSE Enterprise Linux 12-SP5(常规支持结束于 2024 年 10 月)
- Ubuntu 16.04 LTS / Xenial(常规支持结束于 2021 年 4 月)
OpenSSL 1.1.0
发布:2016 年 8 月 生命周期结束:2019 年 9 月
OpenSSL 1.1.0 默认情况下删除或禁用了不安全的密码,并增加了对 ChaCha20-Poly1305、BLAKE2(基本功能)、X25519 和 CT 的支持。大多数结构体都变得不透明,并引入了新的 API。OpenSSL 1.1.0 与 1.0.2 不兼容。
- Debian 9 Stretch(安全支持结束于 2020 年 7 月,LTS 至 2022 年 6 月)
- Ubuntu 18.04 LTS / Bionic(常规支持结束于 2023 年 4 月)
OpenSSL 1.1.1 LTS
发布:2018 年 8 月 生命周期结束:2023 年 9 月(计划)
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 年 6 月发布)
- 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 运行器)
- Packit
- TravisCI(使用
dist: focal
) - Zuul
OpenSSL 3.0.0
发布:n/a(计划于 2021 年年中/年末)
OpenSSL 3.0.0 目前正在开发中。主要变化包括重新许可为 Apache License 2.0 以及用于加密算法提供程序的新 API。大多数更改是内部重构,不影响公共 API。[8]
LibreSSL
创建:2014 年 4 月(从 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 端口有一个端口 security/openssl/1.1
,其文档描述为“[…] 用于支持无法与 LibReSSL 兼容的应用程序” [7]。OpenBSD 可以使用该软件包来提供一个可用的 ssl 模块。
BoringSSL
创建:2014 年 6 月
BoringSSL 是 Google 分支的 OpenSSL。它不适用于一般用途,因此 Python 不支持它。API 或 ABI 稳定性没有保证。Chrome/Chromium 浏览器、Android 和 Apple 平台使用 BoringSSL 的供应商副本 [6]。
优势
TLS 1.3
OpenSSL 1.1.1 引入了对新的 TLS 1.3 版本的支持。最新版本的 TLS 协议握手速度更快,比以前的版本更安全。
线程和派生安全
从 1.1.0c 版本开始,OpenSSL 完全支持分叉和线程安全。绑定不再需要任何解决方法或额外的回调来支持多线程。
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 在 OPENSSL_NO_*
宏的形式下提供了 70 多个配置和构建时选项。大约 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 的一个分支。该分支由 OpenBSD 团队成员于 2014 年在 Heartbleed 漏洞出现后,基于 OpenSSL 1.0.1g 创建。自创建以来,一些被认为存在问题或不安全的特性已被移除或替换(SSL 2.0、SSL 3.0、改进的 CPRNG)或从 OpenSSL 和 BoringSSL 反向移植。
目前,LibreSSL 与 OpenSSL 1.1.1 并不完全兼容。最新版本 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 核心开发团队可能会根据需要反向移植新版本的修复程序或扩展与已过生命周期版本(EOLed)的兼容性。
OpenSSL 的新 ABI 稳定性和 LTS 策略[9] 也应该有所帮助。
保持对 OpenSSL 1.1.0 的支持
有人建议为了与 Debian 9(Stretch)兼容,保留对 OpenSSL 1.1.0 的支持。该提案被拒绝,因为它会使代码清理和测试变得复杂。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