Linux下OPENSSL版本冲突问题及删除libcrypto workaround可行性咨询
问题背景
构建同时链接Qt6 QtNetwork与Python 3.8(miniconda安装)的项目时,运行出现以下错误:
my_prg_bin: symbol lookup error: /lib64/libk5crypto.so.3: undefined symbol: EVP_KDF_ctrl, version OPENSSL_1_1_1b
经排查,冲突根源:
- 系统编译的
libQt6Network.so.6链接系统版libcrypto.so.1.1:ldd libQt6Network.so.6显示libcrypto.so.1.1 => /lib64/libcrypto.so.1.1 - 程序
my_prg_bin因链接Python库,加载了miniconda Python目录下的libcrypto.so.1.1:ldd my_prg_bin显示libcrypto.so.1.1 => /home/me/Python385/lin64/lib/libcrypto.so.1.1 - 系统版
libcrypto.so.1.1包含OPENSSL_1_1_1b版本的EVP_KDF_ctrl符号(objdump -TC /lib64/libcrypto.so.1.1 | grep EVP_KDF可查到),但Python目录下的版本无该符号,二者版本不一致。 - 移除CMakeLists中
target_link_libraries( my_prg_bin /home/me/Python385/lin64/lib/python3.8.so )后,程序不再加载Python目录下的libcrypto,问题消失。
解决OPENSSL版本冲突的方案
方案1:调整运行时库加载优先级
通过修改环境变量LD_LIBRARY_PATH,让系统库目录/lib64优先于Python库目录被加载:
- 运行程序前执行:
export LD_LIBRARY_PATH=/lib64:$LD_LIBRARY_PATH - 若需永久生效,可将该命令添加到用户的
~/.bashrc或程序启动脚本中。
方案2:使用CMake指定链接优先级
在CMakeLists.txt中,将系统OpenSSL库的链接放在Python库之前,确保链接器优先选择系统版本:
# 先链接系统OpenSSL find_package(OpenSSL REQUIRED) target_link_libraries(my_prg_bin PRIVATE OpenSSL::Crypto) # 再链接Python库 target_link_libraries(my_prg_bin PRIVATE /home/me/Python385/lin64/lib/python3.8.so)
方案3:重新编译/安装依赖系统OpenSSL的Python
若允许调整Python环境,可:
- 手动编译Python时指定使用系统OpenSSL:
./configure --with-openssl=/usr make && make install
- 针对miniconda环境,尝试安装依赖系统OpenSSL的Python版本:
conda install python=3.8 openssl=system
方案4:使用rpath控制运行时库搜索路径
在CMake中设置程序的rpath,优先包含系统库目录:
set_target_properties(my_prg_bin PROPERTIES INSTALL_RPATH "/lib64:$ORIGIN/../lib" BUILD_WITH_INSTALL_RPATH ON )
或在链接阶段直接通过参数指定:
gcc -o my_prg_bin ... -Wl,-rpath=/lib64
删除Python目录下libcrypto的安全性分析
从当前测试结果看,删除/home/me/Python385/lin64/lib/libcrypto.so.1.1后,Python和程序均能正常运行,这是因为Python会自动 fallback 到系统的libcrypto.so.1.1。但该方案存在潜在风险:
- 版本兼容性风险:后续miniconda更新Python或相关依赖时,可能会重新安装该库导致冲突复现;若系统OpenSSL版本更新,也可能与Python依赖的版本不兼容,引发新错误。
- 环境一致性问题:其他依赖该miniconda环境的程序可能依赖这个私有libcrypto版本,删除后会导致这些程序运行异常。
- conda管理混乱:手动删除conda环境中的库文件会破坏conda的包管理状态,后续执行
conda update或conda install时可能出现校验错误。
因此,该临时方案仅适合紧急修复,不推荐长期使用,建议采用前面提到的更可靠的方案解决冲突。
内容的提问来源于stack exchange,提问作者jpo38
相关产品推荐
相关产品推荐

