MacOS升级后Python3.9.8的hashlib无法调用RIPEMD160问题求助
故障成因
- OpenSSL 3.0 版本重构了算法分发机制,将RIPEMD160、Whirlpool、MD4等非NIST推荐的旧算法移入了legacy(遗留)算法提供器,默认不会自动加载该提供器。
- MacPorts 打包的 Python 3.9 版本在编译时默认没有配置主动加载 OpenSSL legacy 提供器的逻辑,仅读取了 OpenSSL 上报的全量算法列表填充
hashlib.algorithms_available,没有校验算法实际可调用性,所以会出现「算法显示可用但初始化报错」的矛盾现象。 - 回滚版本无效的核心原因是:当前 MacPorts 生态中所有依赖 OpenSSL 的包都会默认链接最新的 OpenSSL 3.x 版本,只要 OpenSSL 层面没有打开 legacy 提供器,回滚 Python 版本也无法解决问题。
修复方案
按操作复杂度从低到高排列:
方案1:全局开启OpenSSL Legacy提供器(推荐,无需重新编译)
直接修改MacPorts安装的OpenSSL全局配置,一次修改后所有依赖OpenSSL的程序都能调用旧算法:
- 打开OpenSSL配置文件,路径为
/opt/local/etc/openssl/openssl.cnf - 找到
[provider_sect]配置段,修改为以下内容(如果没有对应配置段就直接在文件末尾追加):
[provider_sect] default = default_sect legacy = legacy_sect [default_sect] activate = 1 [legacy_sect] activate = 1
- 保存退出后重新运行Python代码即可生效,无需重启系统。
方案2:重新编译MacPorts Python39(适配不想改全局OpenSSL配置的场景)
如果不想修改全局OpenSSL配置,可以给MacPorts传入编译参数重新构建Python39,让hashlib默认加载legacy提供器:
- 执行以下命令重新编译安装Python39:
sudo port clean python39 sudo port install python39 +openssl_legacy
注:如果当前MacPorts的python39端口没有预置openssl_legacy variant,可以在编译前临时修改Portfile,在hashlib模块的编译参数中加入加载legacy提供器的相关逻辑,或者在Python的sitecustomize.py中加入预加载代码。
方案3:代码层面临时适配(无需修改系统配置,仅对当前脚本生效)
如果只是临时需要运行脚本,不想改动系统环境,可以在调用hashlib之前先手动加载OpenSSL的legacy提供器:
import ctypes import hashlib # 加载MacPorts的OpenSSL 3.x库 libcrypto = ctypes.CDLL("/opt/local/lib/libcrypto.3.dylib") # 加载legacy提供器 OSSL_PROVIDER_load = libcrypto.OSSL_PROVIDER_load OSSL_PROVIDER_load.argtypes = [ctypes.c_void_p, ctypes.c_char_p] OSSL_PROVIDER_load(None, b"legacy") # 现在可以正常调用ripemd160 r160 = hashlib.new('ripemd160')
内容的提问来源于stack exchange,提问作者TnTech
相关产品推荐
相关产品推荐

