2

我想通过 ssl 和端口 995 与我的客户端应用程序与 POP3 服务器通信,服务器证书是自签名的,并且在运行应用程序时收到的错误是:

证书是自签名的,不受信任

一部分代码是:

socket = new QSslSocket(this);
QFile certfile("D:\\hani\\cert\\localhost.localdomain.pem");
Q_ASSERT(certfile.open(QIODevice::ReadOnly));
QList<QSslCertificate> certList;
QSslCertificate cert(&certfile,QSsl::Pem);
certList.append(cert);
socket->addCaCertificate(cert);
socket->setCaCertificates(certList);
QList<QSslCertificate> serverCert = socket->caCertificates();

我能做些什么?

4

2 回答 2

8

不要,让我重复一遍,不要打电话ignoreSslErrors()。它完全违背了 SSL/TLS 的目的。有非常特殊的情况可以安全地调用它,但是这个(自签名证书)并不是一个特殊情况。

以下准备运行的最小代码显示了如何安全地接受服务器自签名证书。不要捷径。

司机:

int main(int argc, char** argv) {
    QCoreApplication app(argc, argv);
    QTextStream log(stdout);
    DummyClient dummy(log);
    QObject::connect(&dummy, SIGNAL(done()), &app, SLOT(quit()));
    return app.exec();
}

DummyClient班级:

/*
 * Show how to safely authenticate a TLS server which uses a self-signed certificate.
 * Warning: No error handling to keep the code short.
 */
class DummyClient : public QObject {
    Q_OBJECT
public:
    DummyClient(QTextStream& log)
        : _log(log),
          _sock(new QSslSocket(this)) {
        connect(_sock, SIGNAL(encrypted()), this, SLOT(onEncrypted()));
        connect(_sock, SIGNAL(sslErrors(QList<QSslError>)),
                this, SLOT(onSslErrors(QList<QSslError>)));
        connect(_sock, SIGNAL(error(QAbstractSocket::SocketError)),
                this, SLOT(onErrors(QAbstractSocket::SocketError)));

        // Trust store: which CAs or self-signed certs we are going to trust.
        //
        // We use setCaCertificates() instead than QSslSocket::addCaCertificates()
        // because we don't want to trust the ~200 default CAs.
        QList<QSslCertificate> trustedCas = QSslCertificate::fromPath("server-cert.pem");
        if (trustedCas.empty()) {
            qFatal("Error: no trusted Cas");
        }
        _sock->setCaCertificates(trustedCas);

        bool mutualAuth = false;
        if (mutualAuth) {
            // Our identity
            _sock->setPrivateKey("client-key.pem");
            _sock->setLocalCertificate("client-cert.pem");
        }

        _log << "Connecting" << endl;
        // Note: serverName must match the cert CN or alternative name.
        Qstring serverName = "myserver.example.org";
        _sock->connectToHostEncrypted(serverName, 995);
    }

signals:
    void done();

private slots:
    void onEncrypted() {
        _log << "onEncrypted" << endl;

        /* Everything is good. Start communicating. */

        emit done();
    }

    void onSslErrors(QList<QSslError> errors) {
        QSslError first = errors.takeFirst();
        _log << "onSslErrors: " << first.errorString() << endl;

        /* Something went wrong in the TLS handshake. Inform the user and quit! */

        emit done();
    }

    void onErrors(QAbstractSocket::SocketError) {
        _log << "onErrors: " << _sock->errorString() << endl;
        emit done();
    }

private:
    QTextStream& _log;
    QSslSocket* _sock;
};
于 2013-10-18T13:05:28.483 回答
0

http://qt-project.org/doc/qt-5.1/qtnetwork/qsslsocket.html

看描述QSslSocket::sslErrors

If you want to continue connecting despite the errors that have occurred,
you must call QSslSocket::ignoreSslErrors() from inside a slot connected 
to this signal.

免责声明:这是非常不明智的,因为它使服务器对中间人攻击“敞开”

于 2013-09-16T07:48:15.123 回答