使用Indy组件发邮件遇SSL3_GET_RECORD版本错误的求助
解决Indy组件连接邮件服务器时的SSL版本不匹配问题
这个error:1408F10B:SSL routines:SSL3_GET_RECORD:wrong version number错误本质是客户端与服务器的SSL/TLS版本协商失败,结合你的场景,核心问题和解决方案如下:
1. 为什么设置[sslvTLSv1]不行?
目前主流邮件服务器(包括Gmail)早已淘汰了TLSv1.0版本:
- Gmail从2020年开始就不再支持TLSv1.0和TLSv1.1,最低要求是TLSv1.2
- 你的私有邮件服务器大概率也配置为只支持TLSv1.2及以上版本
继续使用sslvTLSv1必然会出现版本不匹配的错误。
2. 核心修复步骤
调整SSL版本集合
修改IdSSLIOHandlerSocketOpenSSL1的SSL版本设置,直接指定支持的高版本协议:
// 优先选择TLSv1.2和TLSv1.3,覆盖绝大多数现代服务器 IdSSLIOHandlerSocketOpenSSL1.SSLOptions.SSLVersions := [sslvTLSv1_2, sslvTLSv1_3];
如果你的Indy版本较旧(比如低于10.6.2),可能没有sslvTLSv1_3的定义,至少要包含sslvTLSv1_2:
IdSSLIOHandlerSocketOpenSSL1.SSLOptions.SSLVersions := [sslvTLSv1_2];
检查OpenSSL库版本
Indy依赖OpenSSL动态库,旧版本的OpenSSL(比如1.0.1及以下)不支持TLSv1.2+。请确保:
- 使用OpenSSL 1.1.1及以上版本的库文件(比如
libcrypto-1_1.dll和libssl-1_1.dll) - 将这些DLL放在程序运行目录,或者系统可识别的路径中
匹配SMTP端口与TLS模式
不同端口对应不同的TLS启用方式,以Gmail为例:
- 端口587:使用
STARTTLS,需要设置IdSMTP1.UseTLS := utUseExplicitTLS - 端口465:直接SSL连接,需要设置
IdSMTP1.UseTLS := utUseImplicitTLS
私有邮件服务器请确认其官方文档指定的端口和TLS模式,避免配置不匹配。
完整示例代码
// 配置邮件内容 IdMessage1.Recipients.EMailAddresses := lblFrom.Text; IdMessage1.Subject := lblSubject.Text; IdMessage1.Body.Text := Memo1.Text; // 配置SSL和SMTP参数 IdSSLIOHandlerSocketOpenSSL1.SSLOptions.SSLVersions := [sslvTLSv1_2, sslvTLSv1_3]; IdSMTP1.IOHandler := IdSSLIOHandlerSocketOpenSSL1; // 以Gmail为例的配置(私有服务器替换对应Host/Port/账号) IdSMTP1.Host := 'smtp.gmail.com'; IdSMTP1.Port := 587; IdSMTP1.UseTLS := utUseExplicitTLS; IdSMTP1.Username := 'your-gmail-account@gmail.com'; IdSMTP1.Password := 'your-app-specific-password'; // Gmail需开启两步验证并创建应用专用密码 // 安全发送邮件 try IdSMTP1.Connect; IdSMTP1.Send(IdMessage1); ShowMessage('邮件发送成功'); except on E: Exception do ShowMessage('发送失败:' + E.Message); finally if IdSMTP1.Connected then IdSMTP1.Disconnect; end;
额外注意事项
- Gmail需要开启两步验证,并使用应用专用密码登录,不能直接用普通账号密码
- 私有邮件服务器请检查是否有防火墙、反垃圾邮件规则阻止了你的连接请求
- 如果仍有问题,可以通过在线SSL检测工具(比如SSL Labs)确认服务器支持的具体协议版本
内容的提问来源于stack exchange,提问作者zac
相关产品推荐
相关产品推荐

