Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/qt/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ssl/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
客户端应用程序如何使用Qt中的自签名证书连接到SSL服务器?_Qt_Ssl_Certificate_Self Signed - Fatal编程技术网

客户端应用程序如何使用Qt中的自签名证书连接到SSL服务器?

客户端应用程序如何使用Qt中的自签名证书连接到SSL服务器?,qt,ssl,certificate,self-signed,Qt,Ssl,Certificate,Self Signed,我想用ssl与POP3服务器通信,用我的客户端应用程序与端口995通信 服务器的证书是自签名的,运行应用程序时收到的错误是: 证书是自签名的,不受信任 代码的一部分是: socket = new QSslSocket(this); QFile certfile("D:\\hani\\cert\\localhost.localdomain.pem"); Q_ASSERT(certfile.open(QIODevice::ReadOnly)); QList<QSslCertificate>

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

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

代码的一部分是:

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();
socket=新的QSslSocket(此);
QFile证书文件(“D:\\hani\\cert\\localhost.localdomain.pem”);
Q_断言(certfile.open(QIODevice::ReadOnly));
QList证书列表;
QSsl证书(证书文件(&certfile,QSsl::Pem);
certList.append(cert);
套接字->添加证书(证书);
套接字->设置证书(证书列表);
QList serverCert=socket->caCertificates();
我能做什么?

查看
qsslssocket::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.

免责声明:这是非常不明智的,因为它让服务器“完全开放”给不要调用
忽略错误()
。它完全违背了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;
};
/*
*演示如何安全地验证使用自签名证书的TLS服务器。
*警告:无错误处理以保持代码简短。
*/
类DummyClient:公共QObject{
Q_对象
公众:
DummyClient(QTextStream和日志)
:_log(log),
_袜子(新QSslSocket(本)){
连接(_sock,SIGNAL(encrypted()),this,SLOT(onEncrypted());
连接(_sock,信号(sslErrors(QList)),
这个插槽(onsserrors(QList));
连接(_sock,信号(错误(QAbstractSocket::socketterror)),
这个插槽(onerror(QAbstractSocket::socketterror));
//信任存储:我们将信任哪些CA或自签名证书。
//
//我们使用setCaCertificates()而不是QSslSocket::addCaCertificates()
//因为我们不想信任~200个默认CA。
QList trustedCas=QSslCertificate::fromPath(“server-cert.pem”);
if(trustedCas.empty()){
qFatal(“错误:无可信CA”);
}
_sock->setCaCertificates(受信任的CA);
bool mutualAuth=false;
如果(相互作用){
//我们的身份
_sock->setPrivateKey(“client key.pem”);
_sock->setLocalCertificate(“client-cert.pem”);
}

_日志不遵循此答案(调用ignoreSslErrors)。其效果是客户端将不再对服务器进行身份验证。任何类型的攻击都是可能的,包括中间人。请参阅我的答案。最后,这是一个很好的示例,说明了如何在不忽略ssl错误的情况下正确执行此操作。谢谢。但出于某种原因,QWebsocketServer不接受客户端的证书,尽管它已添加到st或者使用
configuration.setCaCertificates(clientPemCertificate)
。您有这样的例子吗?或者其他解决方案吗?