ESP32 WiFiClientSecure自签根证书验证失败问题求助
ESP32 WiFiClientSecure 自签根证书验证失败问题
我基于ESP32 Arduino的WiFiClientSecure示例开发,替换示例中的根CA为自己的自签根证书后,始终出现SSL验证错误。
代码片段
const char* root_ca = \ "-----BEGIN CERTIFICATE-----\n" \ "MIID3TCCAsWgAwIBAgIIStTO2/9KgZgwDQYJKoZIhvcNAQELBQAwTzELMAkGA1UE\n" \ "BhMCREUxCzAJBgNVBAgTAkhFMRQwEgYDVQQKEwtLYWlzZXJTbWl0aDELMAkGA1UE\n" \ "CxMCQ0ExEDAOBgNVBAMTB0hvbWUtQ0EwIBcNMjMwNjEzMTgxOTAwWhgPMjA3MzA2\n" \ "MTMxODE5MDBaME8xCzAJBgNVBAYTAkRFMQswCQYDVQQIEwJIRTEUMBIGA1UEChML\n" \ "S2Fpc2VyU21pdGgxCzAJBgNVBAsTAkNBMRAwDgYDVQQDEwdIb21lLUNBMIIBIjAN\n" \ "BgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA8QvNdPHqOLeknPljyQZHemTpvH9Y\n" \ "dePyDs1ItzCjwQJA//BK/Kho3iWXnQuKWQ5C3av1qJYK4xR3iLRuZzzyiPEuC4Bg\n" \ "k6O2B+hAfeCy5RKSErzHveCZNCmYJw7HAGv+hoDqu8HEmerkT9Lag1ar0HCtBXvj\n" \ "VZQlzYEkfZvcG6ZSNnl7v5qHTnsI6KTd6OcnNJyFAwgt0hv/3kC/zob9EWq99aCK\n" \ "Yth3cufrq1oDrUREQvVm6kABRnrHwlcHChH3HWuCEyKX3Pf/Rm//cu0vyq87AY9y\n" \ "tHiuVltmufuqpbyFw2cF1DFEPaXFE4W5pwt1NMn550/QvO9qqiGI2kT2FQIDAQAB\n" \ "o4G6MIG3MA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFPOTzLHrzbQbde0QLD9z\n" \ "UXQ33klgMAsGA1UdDwQEAwIBBjBFBgNVHR8EPjA8MDqgOKA2hjRodHRwOi8vY3Js\n" \ "My5kaWdpY2VydC5jb20vRGlnaUNlcnRBc3N1cmVkSURSb290Q0EuY3JsMBEGCWCG\n" \ "SAGG+EIBAQQEAwIABzAeBglghkgBhvhCAQ0EERYPeGNhIGNlcnRpZmljYXRlMA0G\n" \ "CSqGSIb3DQEBCwUAA4IBAQCOSdzCrY0+CUDFCLzqBQn5ZSoDDRWMROwd1mdPPJeT\n" \ "2hAEMzfYsRpH7zr4bOoIVOsIvM/RQWo2h40rWCjjzhVRxlrrIwrWNqte2T3tqJts\n" \ "PwWWy2tFt27i394arjFF+dIxWGvxFgF6P10QS+p9nB0G5oOOVNUa0NV19Kud/Zqa\n" \ "tNvqkYf+Q+rpn3onXXyQVydM1b/K08XdiSMN5m79us0LbmiYZ2kz9yOUrsCDUQPH\n" \ "MvrSAZRbh5JeZHbG60BHg4onii7UmCQsLZIbcybE5+V12btHIh8H/Q7o/e+TM3oI\n" \ "14KmsO31mJCdek6dgssycixPl76nOpEMrbGqh47zY68T\n" \ "-----END CERTIFICATE-----\n"; client.setCACert(root_ca); IPAddress host_ip = {192,168,178,61}; //使用服务器主机名结果一致 const int httpsPort = 8788; Serial.println("\nStarting connection to server..."); if (!client.connect(host_ip, httpsPort)) { Serial.println("Connection failed!"); char err_buf[1000]; if (client.lastError(err_buf,1000)<0) { Serial.print("Last WiFiClientSecure Error: "); Serial.println(err_buf); Serial.println(client.getWriteError()); } } else { ...
问题背景
本地Web服务器采用自签证书体系:自签根CA、根CA签名的中间CA、中间CA签名的服务器证书。已检查系统时间等常见因素,Postman加载证书后可正常请求,但ESP32端无论单独使用某一证书或组合使用,均返回以下错误:
Starting connection to server... Connection failed! Last WiFiClientSecure Error: X509 - Certificate verification failed, e.g. CRL, CA or signature check failed
不想开启不安全模式,怀疑根证书存在问题,请问可能的原因是什么?
排查方向及解决建议
- 证书链不完整:ESP32的WiFiClientSecure不会自动处理中间证书,需将中间CA+根CA拼接成完整证书链(按"中间CA在前,根CA在后"的顺序合并为单个PEM文件),再传入
setCACert。服务器返回的证书链通常仅包含服务器证书和中间CA,若ESP32仅信任根CA,必须确保验证链能完整衔接。 - 根证书格式/算法问题:用
openssl x509 -in root_ca.pem -text -noout验证证书内容,确认换行符无缺失、无多余字符,同时检查签名算法是否为ESP32的mbedTLS支持类型(优先使用SHA-256及以下算法,避免SHA-3等较新算法)。 - 服务器证书SAN字段缺失:若用IP地址连接服务器,服务器证书的
Subject Alternative Name(SAN)字段必须包含该IP;若用主机名连接,SAN需包含对应主机名。mbedTLS对SAN检查严格,缺失会直接验证失败,而Postman可能宽松处理。 - 证书用途扩展不符合要求:
- 根CA证书的
Basic Constraints需设置为CA:TRUE,Key Usage需包含Certificate Sign; - 服务器证书的
Key Usage需包含Digital Signature和Key Encipherment,Extended Key Usage需包含TLS Web Server Authentication。
用openssl命令检查这些扩展是否配置正确。
- 根CA证书的
- 证书行长度不符合PEM标准:PEM格式要求每行最多64个字符,最后一行可缩短。代码中用
\n拼接证书时,需确保每行长度符合要求,否则mbedTLS无法正确解析。
内容的提问来源于stack exchange,提问作者jason.kaisersmith
相关产品推荐
相关产品推荐

