【问题标题】:QSslSocket problemQSslSocket 问题
【发布时间】:2011-03-05 15:15:20
【问题描述】:

我正在尝试创建一个客户端 - 服务器应用程序、用 c++ 和 QT 编写的客户端以及用 java 编写的服务器,但我很难让 ssl 加密工作。
我认为,该过程在握手级别失败。我很难弄清楚它为什么不起作用的原因是,即使进程失败,客户端或服务器都没有报告错误。我在 QT 中使用客户端的休闲方式:

    this->_uCertificate.fromPath(_DC::DEFAULT_CERT_MAIN_PATH + _DC::DEFAULT_MAIN_CERT_FILE);
    this->_socket->addCaCertificate(this->_uCertificate);

    //begin connection
    this->_socket->connectToHostEncrypted(this->_uServerAdress, this->_uServerPort);

    //wait until connection has completed
    if(!this->_socket->waitForConnected(_CM::TIMEOUT))
    {
        this->_lastError = this->_socket->errorString();
        return false;
    }

    //wait for handshake
   if ( !this->_socket->waitForEncrypted(_CM::TIMEOUT) ) {
       this->_lastError =  this->_socket->errorString(); //the error is "No Error"
       //return false;
   }

调用“waitForEncrypted”时失败。该函数返回 false,因此进程失败,但错误字符串为“No Error”。我还添加了一个插槽来处理来自套接字的错误信号,但它从未被调用过。在我使用的服务器端:

 SSLSocket _sock = (SSLSocket) this._ssocket.accept();
_sock.startHandshake();
 ........................................
 if(this._inputBuffered.read(this._messageBuffer) < 0)
                throw new Exception("Error while reading from client");

再次没有抛出异常,但在读取命令时失败。但是在服务器端,如果连接/握手失败,我不确定是否会引发异常,或者我应该以某种方式手动检查错误。
我曾经有一个问题,在客户端,当我收到公用名与主机不匹配的错误时,至少我知道连接有点工作。在我修复证书以包含正确的公用名后,我收到了这个不存在的错误。有谁知道为什么它会以这种方式失败,或者至少有更好的调试方法?

编辑 我尝试使用 openSSL 进行连接,并且可以正常工作。握手成功,我可以从服务器发送和接收数据包。所以问题似乎出在客户端。

【问题讨论】:

  • 您应该使用 Wireshark 来调试此类令人费解的网络问题。我猜连接只是超时了。您能否使用其他工具(如 Web 浏览器或 openssl s_client 命令)与服务器建立 SSL 连接?
  • 在我的情况下,它 QSslSocket 正在触发 QAbstractSocket::error() 信号。

标签: java qt ssl client-server


【解决方案1】:

我从文件加载证书的方式似乎有问题。方法“fromPath”显然实际上并没有从文件中加载证书,而是返回证书列表。如果我将此列表添加到我的套接字,那么它应该可以正常工作。我有点良心不安,因为我没有正确阅读文档。

编辑 它失败但仍然没有抛出信号错误的原因是因为我的套接字没有有效的证书。当我调用 this->_uCertificate.fromPath(..) 时,该方法返回在该路径中找到的证书列表,但对象本身没有被修改。它仍然是一个无效的空证书。所以当我在我的套接字中添加那个空证书时,唯一的一个,当它到达握手时,它没有有效的操作证书。此时它失败了,但没有抛出任何错误。

但是当 .fromPath() 方法返回的对象被添加到套接字时,握手会照常进行,因为现在它具有有效且非空的证书。

【讨论】:

  • 如果你有良心,那么你就是这个网站上不寻常的提问者。
  • 仍然存在未触发 sslErrors 信号的问题。你能为此写一个测试用例吗?
【解决方案2】:

证书数据库为空时无法报错的问题现在是Qt bug QTBUG-17550

【讨论】:

    【解决方案3】:

    将您的 SSL 客户端套接字的 void QSslSocket::sslErrors ( const QList&lt;QSslError&gt; &amp; errors ) 信号连接到某个插槽,看看是否报告了任何 SSL 错误。

    【讨论】:

    • 这样做了,插槽永远不会被调用。
    猜你喜欢
    • 2018-06-26
    • 1970-01-01
    • 2022-07-09
    • 2015-08-09
    • 2018-04-17
    • 2022-10-26
    • 2013-12-05
    • 1970-01-01
    • 2013-02-21
    相关资源
    最近更新 更多