跳转到内容

WiFiClientSecure 设置

WiFiClientSecure 设置

本节详细介绍 ESP32 中 WiFiClientSecure 库的配置方法。WiFiClientSecure 是实现 TLS 加密通信的核心库。学习完成后,您将能够:

  • 正确初始化 WiFiClientSecure
  • 配置 TLS 证书验证参数
  • 处理 TLS 连接状态和错误
  • 优化 TLS 连接性能

在开始本节之前,请确保:

  • 已获取 CA 证书
  • ESP32 支持 TLS 的固件版本
  • 了解基本的 TCP/IP 网络概念
WiFiClientSecure
├── 继承自 WiFiClient
├── 添加 TLS/SSL 功能
├── 支持 mbedTLS 库(ESP32 内部)
├── setCACert() - 设置 CA 证书
├── setCertificate() - 设置客户端证书
├── setPrivateKey() - 设置客户端私钥
├── setInsecure() - 禁用证书验证
├── setTimeout() - 设置超时时间
├── connect() - 建立 TLS 连接
└── verify() - 手动验证证书
#include <WiFiClientSecure.h>
// 全局定义
WiFiClientSecure espClient;
void setupTLS() {
// 方法 1: 使用 CA 证书(推荐生产环境)
espClient.setCACert(rootCACertificate);
// 方法 2: 不验证证书(仅开发测试)
// espClient.setInsecure();
// 方法 3: 双向验证
// espClient.setCACert(rootCACertificate);
// espClient.setCertificate(clientCertificate);
// espClient.setPrivateKey(privateKey);
// 设置超时(可选)
espClient.setTimeout(15000); // 15 秒超时
// 设置缓冲区大小(可选,默认 512 字节)
// espClient.setBufferSizes(1024, 512);
}
void connectWithTLS() {
Serial.print("正在建立 TLS 连接...");
if (espClient.connect(mqtt_server, 8883)) {
Serial.println("TLS 连接成功!");
// 可选:额外验证
if (espClient.verify("mqtt.example.com", rootCACertificate)) {
Serial.println("证书验证通过");
}
} else {
Serial.println("TLS 连接失败");
Serial.printf("错误代码: %d\n", espClient.lastError(NULL, 0));
}
}
WiFiClientSecure 连接状态:
IDLE ──→ connect() ──→ TLS_HANDSHAKE ──→ CONNECTED
│ │
│ (失败) │ (断开)
▼ ▼
ERROR DISCONNECTED
│ │
└──── reconnect() ───┘
enum TLSState {
TLS_IDLE,
TLS_CONNECTING,
TLS_HANDSHAKE,
TLS_CONNECTED,
TLS_ERROR
};
TLSState tlsState = TLS_IDLE;
void handleTLSState() {
switch (tlsState) {
case TLS_IDLE:
if (WiFi.status() == WL_CONNECTED) {
tlsState = TLS_CONNECTING;
}
break;
case TLS_CONNECTING:
Serial.println("发起 TLS 连接...");
if (espClient.connect(mqtt_server, 8883)) {
tlsState = TLS_CONNECTED;
Serial.println("TLS 连接成功");
} else {
tlsState = TLS_ERROR;
Serial.println("TLS 连接失败");
}
break;
case TLS_CONNECTED:
// 正常通信
if (!espClient.connected()) {
tlsState = TLS_DISCONNECTED;
}
break;
case TLS_ERROR:
// 等待重试
delay(5000);
tlsState = TLS_IDLE;
break;
}
}
// 连接超时
espClient.setTimeout(10000); // 10 秒
// 自定义连接超时(不依赖 setTimeout)
unsigned long connectWithTimeout(const char* host, int port, int timeoutSec) {
unsigned long start = millis();
espClient.connect(host, port);
while (!espClient.connected()) {
if (millis() - start > (unsigned long)(timeoutSec * 1000)) {
Serial.println("连接超时");
return 0;
}
delay(100);
}
return millis() - start; // 返回连接耗时
}
// 使用示例
unsigned long elapsed = connectWithTimeout("mqtt.example.com", 8883, 15);
if (elapsed > 0) {
Serial.printf("TLS 连接成功,耗时: %lu ms\n", elapsed);
}
条件TLS 握手时间备注
TLS 1.2 + ECDHE1-2 秒最常用
TLS 1.30.5-1 秒更快
证书验证+0.5-1 秒包含证书链验证
弱 WiFi 信号3-5 秒可能超时
总计(典型)2-4 秒首次连接
void checkTLSStatus() {
int error = espClient.lastError(NULL, 0);
switch (error) {
case 0:
Serial.println("TLS 状态正常");
break;
case MBEDTLS_ERR_SSL_CONN_EOF:
Serial.println("TLS 连接被服务器关闭");
break;
case MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE:
Serial.println("TLS 握手失败 - 检查证书和版本");
break;
case MBEDTLS_ERR_SSL_CA_CHAIN_VERIFY_FAILED:
Serial.println("CA 证书链验证失败 - 检查根证书");
break;
case MBEDTLS_ERR_SSL_CERTIFICATE_VERIFY_FAILED:
Serial.println("证书验证失败 - 检查服务器证书");
break;
case MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE:
Serial.println("服务器证书无效或已过期");
break;
default:
Serial.printf("未知 TLS 错误: %d\n", error);
break;
}
}
// 优化 TLS 连接的内存使用
// 1. 减少 TLS 缓冲区大小(默认 16KB)
espClient.setBufferSizes(4096, 512); // 接收 4KB,发送 512B
// 2. 使用预共享密钥(PSK)替代证书(如果 Broker 支持)
// 不需要 CA 证书,节省 Flash 空间
// espClient.setPreSharedKey(psk_ident, psk_key);
// 3. 监控 TLS 内存使用
void monitorTLSMemory() {
Serial.printf("Free heap: %d bytes\n", ESP.getFreeHeap());
Serial.printf("Free PSRAM: %d bytes\n", ESP.getFreePsram());
Serial.printf("TLS buffer: ~10KB\n");
}
// 4. 断开连接后释放资源
void disconnectTLS() {
espClient.stop();
// WiFiClientSecure 析构自动释放 TLS 上下文
}
特性说明
零成本ESP32 内置硬件加密加速,无需额外芯片
内存占用TLS 连接约占用 10-15KB 堆内存
连接时间首次 TLS 握手 2-4 秒
兼容性支持 TLS 1.2/1.3,兼容大部分云平台
灵活性支持 CA 验证、双向验证、PSK 三种模式

本节介绍了 WiFiClientSecure 库的配置:

  1. 初始化:setCACert() / setInsecure() / 双向验证
  2. 超时管理:setTimeout() 和自定义超时逻辑
  3. 状态管理:TLS 连接状态机
  4. 错误处理:TLS 错误码识别和恢复
  5. 内存优化:缓冲区调整、PSK 替代证书、断开释放资源