ThinkPHP邮件加密配置需匹配协议与端口:QQ邮箱用ssl+465,163等用tls+587;须启用OpenSSL扩展、PHP≥8.0,并通过env()读取.env中MAIL_ENCRYPTION等变量。

如果您在 ThinkPHP 项目中配置邮件发送功能,但邮件内容未加密或传输过程被拦截,则可能是 SMTP 加密方式配置错误或缺失。以下是针对不同场景配置邮件加密方式的具体操作步骤:
一、配置 SMTP 传输层加密(SSL/TLS)
该方式用于保障邮件在客户端与 SMTP 服务器之间传输过程的安全性,防止中间人窃听。ThinkPHP 6.1+ 使用 symfony/mailer 底层,必须正确匹配加密协议与端口。
1、打开 config/mail.php 文件,定位到 'smtp' 配置块。
2、根据所用邮箱服务商选择对应参数组合:
QQ 邮箱:设置 'encryption' => 'ssl' 且 'port' => 465;
163 邮箱或多数国际 SMTP 服务:设置 'encryption' => 'tls' 且 'port' => 587。
立即学习“PHP免费学习笔记(深入)”;
3、确认 PHP 环境已启用 OpenSSL 扩展:检查 php.ini 中 extension=openssl 未被注释,重启 Web 服务。
二、使用环境变量动态配置加密参数
该方式可避免敏感配置硬编码,提升多环境部署安全性,同时便于统一管理加密策略。
1、在项目根目录的 .env 文件中添加以下行:
MAIL_ENCRYPTION=ssl
MAIL_PORT=465
2、修改 config/mail.php 中 smtp 配置项:
'encryption' => env('MAIL_ENCRYPTION', 'ssl'),
'port' => (int)env('MAIL_PORT', 465),
3、确保 env() 函数能正常读取变量——验证方法为在控制器中执行 var_dump(env('MAIL_ENCRYPTION')),输出应为字符串 ssl 或 tls。
三、强制启用 STARTTLS 协议升级
当 SMTP 服务器支持明文连接但要求后续升级为加密通道时,需显式启用 STARTTLS 行为,适用于部分企业邮箱或自建 Postfix 服务。
1、在 config/mail.php 的 smtp 配置中添加字段:
'stream_context_options' => [
'ssl' => [
'allow_self_signed' => true,
'verify_peer' => false,
'verify_peer_name' => false
]
],
2、将 'encryption' 设置为 'tls',即使端口为 25 或 587,symfony/mailer 会自动发起 STARTTLS 命令。
3、若出现 "Unable to connect with TLS" 错误,需检查 PHP 版本是否 ≥ 8.0,并确认 OpenSSL 支持 TLS 1.2+。
四、对邮件正文内容进行 AES 对称加密
该方式在 SMTP 传输加密之外,进一步对邮件正文实施端到端加密,确保即使传输链路被突破,内容仍不可读。
1、生成 32 字节密钥并安全存储:
$key = hash('sha256', 'your_secret_passphrase', true);
2、在发送前对正文加密:
$iv = random_bytes(16);
$encrypted_body = openssl_encrypt($original_body, 'aes-256-cbc', $key, OPENSSL_RAW_DATA, $iv);
$payload = base64_encode($iv . $encrypted_body);
3、设置邮件正文为加密载荷,并声明编码格式:
$mail->Body = $payload;
$mail->CharSet = 'us-ascii';
$mail->ContentType = 'text/plain; charset="us-ascii"';
五、集成 GnuPG 实现 PGP 非对称加密
该方式适用于高安全要求场景,如内部系统间通信,由收件方公钥加密、私钥解密,无需共享密钥。
1、安装 GnuPG 工具并生成密钥对:
gpg --gen-key
gpg --export -a "Recipient Name" > public.key
2、在发送端使用收件人公钥加密正文:
$gpg = new \gnupg();
$gpg->addencryptkey('recipient_fingerprint');
$encrypted = $gpg->encrypt($original_body);
3、将加密结果赋值给邮件正文,并设置 MIME 类型为 application/pgp-encrypted:
$mail->Body = $encrypted;
$mail->ContentType = 'application/pgp-encrypted';



















