Python错误:需要OpenSSL1.1.1或更高版本

Python 错误:需要 OpenSSL 1.1.1 或更高版本

在使用 Python 进行网络编程、加密操作或者使用依赖于 OpenSSL 的第三方库(如 requestscryptography 等)时,你可能会遇到类似以下的错误信息:

ImportError: urllib3 v2.0 only supports OpenSSL 1.1.1+, currently the 'ssl' module is compiled with 'OpenSSL 1.0.2k-fips 26 Jan 2017'. See: https://github.com/urllib3/urllib3/issues/2168
或者
ImportError: dlopen(/.../site-packages/cryptography/hazmat/bindings/_openssl.abi3.so, 2): Library not loaded: /usr/local/opt/openssl/lib/libssl.1.0.0.dylib
Referenced from: /.../site-packages/cryptography/hazmat/bindings/_openssl.abi3.so
Reason: image not found

或者更通用的:

This version of Python requires OpenSSL 1.1.1 or newer.

这些错误都表明你的 Python 环境使用的 OpenSSL 版本过旧,低于要求的 1.1.1 版本。 一些较新的 Python 版本(例如 Python 3.7 及更高版本)或者第三方库为了安全性、性能和新特性的支持,明确要求使用 OpenSSL 1.1.1 或更高版本。OpenSSL 1.0.2 系列已于 2019 年 12 月 31 日停止支持 (End-of-Life, EOL),因此升级是必要的。

问题原因分析:

  1. 系统 OpenSSL 版本过旧: 你的操作系统自带的 OpenSSL 版本可能太旧,无法满足 Python 或其依赖库的要求。

  2. Python 使用了错误的 OpenSSL 库: 即使你的系统上安装了较新版本的 OpenSSL,Python 也可能没有正确链接到它。这可能是由于环境变量配置问题、多个 OpenSSL 版本共存导致的冲突,或者在安装 Python 或相关库时使用了旧版本的 OpenSSL。

  3. 虚拟环境问题(Virtual Environments): 如果你在使用虚拟环境(如 venvconda),问题可能局限于该环境。虚拟环境可能链接到了系统旧版本的 OpenSSL,或者没有正确安装新版本的 OpenSSL。

  4. 使用了需要更高OpenSSL版本的第三方库,例如使用了urllib3>=2.0

解决方法:

解决此问题的关键在于更新 OpenSSL 并确保 Python 正确链接到新版本。 根据你的操作系统和具体情况,以下是一些常见的解决方法:

1. Linux 系统(Ubuntu/Debian、CentOS/RHEL/Fedora):

  • Ubuntu/Debian:

    ```bash
    sudo apt update
    sudo apt install libssl-dev # 安装开发包,包含头文件
    sudo apt install openssl # 确保 openssl 也是最新

    如果需要特定版本 (例如 1.1.1k), 尝试:

    sudo apt install openssl=1.1.1k-1ubuntu2.1 # 替换为具体的版本号

    安装完后,如果问题依旧,尝试重新编译Python或者重新安装依赖库。 对于已经安装的Python,可能需要重新编译Python。bash
    ./configure --with-openssl=/usr/local/openssl #--with-openssl 后面指定 openssl 的安装目录
    ```

  • CentOS/RHEL/Fedora:

    ```bash
    sudo yum update
    sudo yum install openssl-devel # 安装开发包
    sudo yum install openssl # 确保openssl也是最新

    或使用 dnf (Fedora 22+)

    sudo dnf update

    sudo dnf install openssl-devel

    ```
    安装后处理方式同Ubuntu。

  • 源码编译安装 OpenSSL (适用于需要特定版本或无法通过包管理器安装的情况):
    如果你的系统包管理器没有提供足够新的 OpenSSL 版本,或者你需要一个特定的版本,可以从 OpenSSL 官网下载源码进行编译安装。以下是一个通用的步骤(具体路径和版本号请根据实际情况修改):

    bash
    wget https://www.openssl.org/source/openssl-1.1.1t.tar.gz # 下载源码 (替换为最新版本)
    tar -xf openssl-1.1.1t.tar.gz
    cd openssl-1.1.1t
    ./config --prefix=/usr/local/openssl --openssldir=/usr/local/openssl shared zlib # 配置安装路径
    make
    sudo make install

    安装完成后,需要配置环境变量,使系统能够找到新安装的 OpenSSL:
    ```bash

    将以下内容添加进/etc/profile文件中

    export PATH=$PATH:/usr/local/openssl/bin
    export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/openssl/lib
    source /etc/profile #立即生效
    ```
    接着重新编译Python。

2. macOS 系统:

  • 使用 Homebrew (推荐):

    bash
    brew update
    brew install [email protected] # 安装 OpenSSL 1.1.x 版本
    brew install openssl@3 # 如果你需要 OpenSSL 3.x 版本

    Homebrew 会将 OpenSSL 安装到 /usr/local/opt/[email protected]/ (或 @3) 目录下。 安装后,可能需要设置环境变量:

    bash
    echo 'export PATH="/usr/local/opt/[email protected]/bin:$PATH"' >> ~/.bash_profile # 或 ~/.zshrc
    echo 'export LDFLAGS="-L/usr/local/opt/[email protected]/lib"' >> ~/.bash_profile # 或 ~/.zshrc
    echo 'export CPPFLAGS="-I/usr/local/opt/[email protected]/include"' >> ~/.bash_profile # 或 ~/.zshrc
    source ~/.bash_profile # 或 source ~/.zshrc

    对于已经安装的Python,可能需要重新编译Python,并指定OpenSSL路径:

    bash
    ./configure --with-openssl=/usr/local/opt/[email protected]
    make
    sudo make install

    * 如果使用了pyenv, 可以使用如下命令重新安装python, 使其自动链接到新安装的openssl:
    bash
    env \
    PATH=$(brew --prefix [email protected])/bin:$PATH \
    LDFLAGS="-L$(brew --prefix [email protected])/lib" \
    CPPFLAGS="-I$(brew --prefix [email protected])/include" \
    PYTHON_CONFIGURE_OPTS="--with-openssl=$(brew --prefix [email protected])" \
    pyenv install 3.9.13 # 替换为您要安装的版本

3. Windows 系统:

  • 下载并安装 OpenSSL 二进制文件:
    从 OpenSSL 官方网站或第三方可信来源(如 Shining Light Productions: https://slproweb.com/products/Win32OpenSSL.html)下载适用于 Windows 的 OpenSSL 二进制安装包。 选择与你的 Python 版本(32 位或 64 位)匹配的安装包,并确保安装的是 1.1.1 或更高版本。 安装时,请注意安装路径,并选择将 OpenSSL 的 bin 目录添加到系统环境变量 PATH 中。

  • 手动设置环境变量 (如果安装程序没有自动设置):
    在"系统属性" -> "高级" -> "环境变量" 中,找到 "系统变量" 下的 Path 变量,编辑它,添加 OpenSSL 的 bin 目录的路径(例如 C:\Program Files\OpenSSL-Win64\bin)。
    同样,可能需要添加OPENSSL_CONF指明openssl.cfg文件的位置。

  • 重新安装依赖的Python包: 安装完新的 OpenSSL 并设置好环境变量后, 你可能需要重新安装依赖的 Python 包,以便它们能够链接到新的 OpenSSL 库。 可以使用 pip install --upgrade --force-reinstall package_name 来强制重新安装。

4. 虚拟环境 (Virtual Environments):

如果你在使用虚拟环境,请确保在激活虚拟环境后执行上述操作。 例如,使用 venv

bash
source myenv/bin/activate # 激活虚拟环境 (Linux/macOS)
myenv\Scripts\activate # 激活虚拟环境 (Windows)
pip install --upgrade --force-reinstall requests cryptography # 重新安装依赖包

对于conda环境:

bash
conda activate myenv
conda install openssl=1.1.1 # 或者你需要的特定版本
conda install -c conda-forge <package_name> # 使用 conda-forge 重新安装依赖包

如果conda install openssl 无法安装到合适的版本,可以考虑使用 conda-forge channel:
bash
conda config --add channels conda-forge
conda install openssl

5. 检查 Python 使用的 OpenSSL 版本:

完成上述步骤后,可以使用以下 Python 代码检查 Python 当前使用的 OpenSSL 版本:

python
import ssl
print(ssl.OPENSSL_VERSION)

如果输出的版本号是 1.1.1 或更高,则问题已解决。

总结:

解决 "需要 OpenSSL 1.1.1 或更高版本" 错误的关键在于:

  1. 更新 OpenSSL: 使用系统包管理器或从源码编译安装最新版本的 OpenSSL。
  2. 正确链接: 确保 Python 能够找到并使用新安装的 OpenSSL 库。 这可能涉及到设置环境变量、重新编译 Python 或重新安装依赖包。
  3. 虚拟环境: 如果使用虚拟环境,请在激活的环境中进行操作。
  4. 验证: 使用 ssl.OPENSSL_VERSION 检查 Python 使用的 OpenSSL 版本是否已更新。

通过以上步骤,你应该能够解决 Python 中 OpenSSL 版本过低的问题,并顺利使用依赖于 OpenSSL 的功能和库。 请根据你的具体操作系统和环境选择合适的解决方法。 如果问题仍然存在,请仔细检查错误信息,并尝试搜索更具体的解决方案。

THE END