You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Qt WebSocket无法信任Apache2及浏览器验证通过的SSL证书

Qt5 WebSocket服务端SSL证书信任问题排查方案

问题核心

服务端使用正式SSL证书后,Apache和浏览器可正常访问,但Qt客户端(含官方示例)无法信任证书,抛出错误:

The issuer certificate of a locally looked up certificate could not be found

根源是Qt的SSL栈无法找到证书链中的颁发者证书(中间/根证书),导致验证失败。

排查与解决步骤

1. 确认证书链完整性

多数CA颁发的证书需要完整的证书链(服务器证书 + 中间证书 + 根证书)才能被客户端正常验证。你当前使用的certificate.crt可能仅包含服务器证书,缺少中间证书:

  • 登录CA后台,下载完整的证书链文件(通常命名为fullchain.pem或类似)
  • 用openssl x509 -in certificate.crt -text -noout查看证书的Issuer字段,确认对应的中间证书是否存在于你的证书文件中

2. 修改服务端SSL配置代码

Qt需要明确加载完整的证书链,而非仅服务器证书。修改代码如下:

QSslConfiguration sslConfiguration;
// 加载完整证书链文件(包含服务器+中间+根证书,PEM格式)
QFile certFile("./crt/full_chain.crt");
QFile keyFile("./crt/private.key");

if (!certFile.open(QIODevice::ReadOnly) || !keyFile.open(QIODevice::ReadOnly)) {
    qCritical() << "Failed to open certificate/key files";
    return;
}

// 读取所有证书(链中的每个证书)
QList<QSslCertificate> caCerts = QSslCertificate::fromDevice(&certFile, QSsl::Pem);
// 重置文件指针到开头,读取服务器证书(链中第一个通常是服务器证书)
certFile.seek(0);
QSslCertificate serverCert(&certFile, QSsl::Pem);

QSslKey sslKey(&keyFile, QSsl::Rsa, QSsl::Pem);
certFile.close();
keyFile.close();

// 配置CA证书链
sslConfiguration.setCaCertificates(caCerts);
// 设置服务器证书和私钥
sslConfiguration.setLocalCertificate(serverCert);
sslConfiguration.setPrivateKey(sslKey);

// 可根据需求调整验证模式(发布阶段建议启用客户端验证,若需要)
// sslConfiguration.setPeerVerifyMode(QSslSocket::VerifyPeer);

qInfo() << "Server cert issuer:" << serverCert.issuerDisplayName();
qInfo() << "Server cert subject:" << serverCert.subjectDisplayName();

m_pWebSocketServer->setSslConfiguration(sslConfiguration);

3. 验证Qt SSL后端环境

Qt默认依赖系统OpenSSL库,需确认其信任库包含你的CA根证书:

  • 在代码中添加以下输出,检查SSL版本和默认CA证书数量:
    qInfo() << "OpenSSL version:" << QSslSocket::sslLibraryVersionString();
    qInfo() << "Default CA certs count:" << QSslSocket::defaultCaCertificates().size();
    
  • 如果默认CA数量过少,说明系统OpenSSL信任库未包含你的CA根证书,可手动将根证书添加到系统信任库,或在代码中通过setCaCertificates加载根证书文件

4. 用OpenSSL命令测试服务端证书链

执行以下命令,检查服务端是否发送完整证书链:

openssl s_client -connect your_domain:your_port

查看输出中的Certificate chain部分,若仅显示服务器证书,说明服务端未配置完整链,需重新替换证书文件为完整链文件


内容的提问来源于stack exchange,提问作者1138

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.12 20:35:11