Python 3.8环境hashlib调用MD4报unsupported hash type错误如何解决
问题原因
- 你当前使用的Python环境搭载的是OpenSSL 3.0及以上版本,该版本默认将MD4归类为不安全的遗留算法,在默认加载策略中对其做了禁用处理。
hashlib.algorithms_available仅会枚举OpenSSL支持的所有算法,不会校验算法是否被当前策略允许调用,因此会出现列表中存在MD4但实际无法使用的情况。 - 你在系统命令行中调用的openssl和conda虚拟环境内Python绑定的openssl是独立的两套程序,系统openssl的策略可能已经放开了MD4的限制,但conda环境内的openssl仍使用默认受限策略,因此两者表现不一致。
解决方法
方法1:运行时临时加载OpenSSL遗留算法提供者(无需修改配置,推荐)
在你所有业务代码执行前,先通过ctypes调用OpenSSL接口加载legacy算法提供者,即可正常使用MD4:
import ctypes import os from ctypes import CDLL # 适配不同系统的OpenSSL crypto库加载逻辑 if os.name == 'nt': # Windows conda环境默认的crypto库名 libcrypto = CDLL('libcrypto-3-x64.dll') else: # Linux环境默认crypto库名 libcrypto = CDLL('libcrypto.so.3') # 注册legacy和default算法提供者 libcrypto.OSSL_PROVIDER_load.argtypes = [ctypes.c_void_p, ctypes.c_char_p] libcrypto.OSSL_PROVIDER_load(None, b'legacy') libcrypto.OSSL_PROVIDER_load(None, b'default') # 测试验证 import hashlib print(hashlib.new('md4', b'test').hexdigest())
方法2:修改conda环境OpenSSL配置永久生效
找到你的conda虚拟环境下的openssl配置文件,路径通常为C:\ProgramData\Miniconda3\envs\victory\ssl\openssl.cnf,修改内容如下:
- 在文件最顶部添加配置指向:
openssl_conf = default_conf
- 在文件最底部添加遗留算法启用配置:
[default_conf] ssl_conf = ssl_sect [ssl_sect] system_default = system_default_sect [system_default_sect] CipherString = DEFAULT:@SECLEVEL=0 Providers = provider_sect [provider_sect] default = default_sect legacy = legacy_sect [default_sect] activate = 1 [legacy_sect] activate = 1
修改完成后保存文件,重启虚拟环境即可永久生效。
方法3:替换MD4实现为纯Python版本
如果不想修改OpenSSL相关配置,可以安装纯Python实现的MD4算法库,通过猴子补丁替换hashlib的默认调用:
- 先安装依赖:
pip install pycryptodome
- 在业务代码开头添加补丁逻辑:
from Crypto.Hash import MD4 import hashlib # 保存原hashlib.new方法 original_hashlib_new = hashlib.new def patched_hashlib_new(algo, data=b'', **kwargs): if algo.lower() == 'md4': return MD4.new(data) return original_hashlib_new(algo, data, **kwargs) # 替换默认方法 hashlib.new = patched_hashlib_new
补丁生效后,ntlm-auth库调用hashlib生成MD4时会自动使用pycryptodome的实现,不会再触发报错。
内容的提问来源于stack exchange,提问作者spitoglou
相关产品推荐
相关产品推荐

