不要,让我重复一遍,不要打电话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;
};