升级Delphi开发的Indy库以适配最新OpenSSL(含TLS 1.3)的流程
升级Indy库适配支持TLS 1.3的最新OpenSSL库
我之前也踩过这个坑——光改DLL文件名完全没用,OpenSSL 1.1+的API和旧版(1.0.x及更早)差异太大,Indy的Pascal绑定代码必须跟着同步更新才行。下面是我总结的一步步解决方法:
1. 先升级到最新版Indy(省超多事)
首先建议直接把你的Indy库升级到10.6.2及以后的稳定版,官方其实已经针对OpenSSL 1.1.x做了大量适配工作,包括TLS 1.3的支持。如果你的Indy版本太老,直接替换成官方最新的IdSSL系列源文件,能省掉大部分重复造轮子的工作。
2. 更新DLL名称与加载逻辑
旧版Indy依赖的libssl32.dll/ssleay32.dll是OpenSSL 1.0.x的产物,1.1.x及以后的DLL命名规则变了:32位是libssl-1_1.dll/libcrypto-1_1.dll,64位是libssl-1_1-x64.dll/libcrypto-1_1-x64.dll。
你需要修改IdSSLOpenSSLUtils.pas里的常量定义,最好加上64位的条件编译:
{$IFDEF WIN64} const LIBSSL_NAME = 'libssl-1_1-x64.dll'; LIBCRYPTO_NAME = 'libcrypto-1_1-x64.dll'; {$ELSE} const LIBSSL_NAME = 'libssl-1_1.dll'; LIBCRYPTO_NAME = 'libcrypto-1_1.dll'; {$ENDIF}
3. 同步OpenSSL 1.1+的API绑定(核心工作)
OpenSSL 1.1.x重构了大量内部结构,很多函数签名、类型定义都变了,必须更新IdSSLOpenSSLHeaders.pas和IdSSLOpenSSLHeaders_static.pas:
- 替换旧类型:比如
SSL_METHOD在1.1.x里变成了不透明指针,不能直接访问内部字段,要改用TLS_method()这类新API替代旧的TLSv1_method() - 更新函数声明:比如
SSL_CTX_new()的参数从SSL_METHOD*改成了const SSL_METHOD*,还要新增SSL_CTX_set_min_proto_version()、SSL_CTX_set_max_proto_version()这类用于指定TLS版本范围的函数 - 移除废弃API:比如
SSL_library_init()已经被废弃,要换成OPENSSL_init_ssl()和OPENSSL_init_crypto()来初始化
4. 调整IdSSLOpenSSL.pas的核心逻辑
这个文件里的业务逻辑要适配新API:
- 替换OpenSSL初始化代码:把旧的
SSL_library_init()等调用换成1.1.x的初始化流程 - 开启TLS 1.3支持:创建
TIdSSLIOHandlerSocketOpenSSL后,通过SSL_CTX_set_min_proto_version()设置最小版本为TLS1_3_VERSION,或者直接用TLS_client_method()/TLS_server_method(),这类方法会自动支持包括TLS 1.3在内的所有兼容协议版本 - 适配会话、证书相关逻辑:比如
SSL_get_peer_certificate()的返回值处理方式在1.1.x里有变化,需要对应调整
5. 编译测试
把修改后的所有IdSSL相关单元重新编译,替换原来的Indy包。然后做验证:
- 连接一个支持TLS 1.3的站点(比如Google、Cloudflare的站点),用Wireshark抓包确认协议版本
- 排查加载DLL失败、API调用异常的问题,根据报错信息调整绑定代码
额外注意事项
- 如果你不想自己折腾,直接用官方适配好的Indy版本是最优解,Indy 10.6.2+已经原生支持OpenSSL 1.1.x和TLS 1.3
- 老版本Delphi(比如XE及更早)可能需要额外调整代码,因为部分新语法支持不足
- 部署时要把对应版本的OpenSSL DLL和程序打包,注意区分32位/64位版本
内容的提问来源于stack exchange,提问作者Flaviu




