You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多
文档控制台
免费开始使用

升级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.pasIdSSLOpenSSLHeaders_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

火山引擎 最新活动