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带QSslSocket未正确连接_Qt_Ssl_Qsslsocket - Fatal编程技术网

Qt带QSslSocket未正确连接

Qt带QSslSocket未正确连接,qt,ssl,qsslsocket,Qt,Ssl,Qsslsocket,我有一个客户机-服务器应用程序正在使用qtcsocket。现在我想改用加密的SSL连接,因此我尝试切换到QSslSocket。但我无法建立到服务器的连接。 以下是客户端的代码: ConnectionHandler::ConnectionHandler(QString ip, int port, QObject *parent) : QObject(parent) { // connect(this->socket, SIGNAL(connected()), this, SLOT(co

我有一个客户机-服务器应用程序正在使用
qtcsocket
。现在我想改用加密的SSL连接,因此我尝试切换到
QSslSocket
。但我无法建立到服务器的连接。 以下是客户端的代码:

ConnectionHandler::ConnectionHandler(QString ip, int port, QObject *parent) : QObject(parent) {
//    connect(this->socket, SIGNAL(connected()), this, SLOT(connected()));
    connect(this->socket, SIGNAL(disconnected()), this, SLOT(disconnected()));
    connect(this->socket, SIGNAL(readyRead()), this, SLOT(readyRead()));
    connect(this->socket, SIGNAL(encrypted()), this, SLOT(encryptedReady()));
    connect(this->socket, SIGNAL(sslErrors(const QList<QSslError> &)), this, SLOT(SSLerrorOccured(const QList<QSslError> &)));
    connect(this->socket, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(socketError(QAbstractSocket::SocketError)));
    connect(this->socket, SIGNAL(stateChanged(QAbstractSocket::SocketState)), this, SLOT(socketStateChanged(QAbstractSocket::SocketState)));

    this->ip = ip;
    this->port = port;
}


void ConnectionHandler::socketStateChanged(QAbstractSocket::SocketState state) {
    qDebug() << state;
}


void ConnectionHandler::socketError(QAbstractSocket::SocketError) {
    qDebug() << this->socket->errorString();
}


void ConnectionHandler::encryptedReady() {
    qDebug() << "READY";

}


void ConnectionHandler::SSLerrorOccured(const QList<QSslError> &) {
    qDebug() << "EEROR";
}


void ConnectionHandler::connectToServer() {
//    this->socket->connectToHost(this->ip, this->port);
    this->socket->connectToHostEncrypted(this->ip, this->port);

    if (!this->socket->waitForConnected(5000)) {
    this->socket->close();
    this->errorMsg = this->socket->errorString();
    }
}


void ConnectionHandler::connected() {
qDebug() << "connected";
    this->connectedHostAddress = this->socket->peerAddress().toString();
    this->connectionEstablished = true;
    this->localIP = this->socket->localAddress().toString();
    this->localPort = this->socket->localPort();
} 
sslErrorOccured: ("The certificate is self-signed, and untrusted")
对于服务器:

 ClientHandler::ClientHandler() {
    this->socket->setProtocol(QSsl::SslV3);
    this->socket->setSocketOption(QAbstractSocket::KeepAliveOption, true);
}

void ClientHandler::run() {
    if (!this->fd)
    return;

    connect(this->socket, SIGNAL(readyRead()), this, SLOT(readyRead()));
    connect(this->socket, SIGNAL(disconnected()), this, SLOT(disconnected()), Qt::DirectConnection);
    connect(this->socket, SIGNAL(encrypted()), this, SLOT(encryptedReady()));
    connect(this->socket, SIGNAL(sslErrors(const QList<QSslError> &)), this, SLOT(sslErrorOccured(const QList<QSslError> &)));
    connect(this->socket, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(socketError(QAbstractSocket::SocketError)));
    connect(this->socket, SIGNAL(stateChanged(QAbstractSocket::SocketState)), this, SLOT(socketStateChanged(QAbstractSocket::SocketState)));

    if (!this->socket->setSocketDescriptor(this->fd)) {
    emit error(socket->error());
    return;
    } else {
    connect(this->socket, SIGNAL(encrypted()), this, SLOT(ready()));
    this->socket->startServerEncryption();
    }

    this->peerIP = socket->peerAddress().toString();
    QString tmp;
    tmp.append(QString("%1").arg(socket->peerPort()));
    this->peerPort = tmp;

    QHostInfo::lookupHost(this->peerIP, this, SLOT(lookedUp(QHostInfo)));
}


void ClientHandler::socketStateChanged(QAbstractSocket::SocketState state) {
    qDebug() << state;
}


void ClientHandler::socketError(QAbstractSocket::SocketError) {
    qDebug() << this->socket->errorString();
}


void ClientHandler::setFileDescriptor(int fd) {
    this->fd = fd;
}

void ClientHandler::ready() {
    qDebug() << "READY";
}

void ClientHandler::sslErrorOccured(const QList<QSslError> &) {
    qDebug() << "EEROR";
}


void ClientHandler::encryptedReady() {
    qDebug() << "READY";

}
  QAbstractSocket::ConnectedState
  "Error during SSL handshake: error:1408A0C1:SSL routines:SSL3_GET_CLIENT_HELLO:no shared cipher"
  QAbstractSocket::UnconnectedState

有人知道如何解决这个问题吗?

我认为使用非加密套接字一切正常。因此,让我们只关注使用
qsslssocket
进行详细说明的特性。如果需要,我可以分享更大的片段或工作代码。还有一个关于SSL证书的大故事,我将在这里简要介绍一下

首先,让我们检查一些外部HTTP SSL服务器上的客户端,例如:

socket->connectToHostEncrypted("gmail.com", 443);
它应该立即使用默认SSL协议(不带任何
setProtocol()
)。在信号
encrypted()
上,您可以写入HTTP GET头,在
readyRead()
上会出现回复

现在尝试设置
socket->setProtocol(QSsl::SslV3)用于
“gmail.com”
。预期结果:

sslErrorOccured: ("The host name did not match any of the valid hosts for this certificate")
请注意,它不是
error()
信号,而是通知客户端可以忽略的证书问题的
sslErrors()
信号

因此,为了简单起见,让我们使用默认SSL协议,而不使用
setProtocol()

由于客户端处于工作状态,我们可以移动到服务器。您在第一级SSL认证挑战中被打断。要开始由服务器初始化SSL连接,您必须至少提供私有加密密钥和公共证书。这就是你的错误:

"Error during SSL handshake: error:1408A0C1:SSL routines:SSL3_GET_CLIENT_HELLO:no shared cipher"
在最理想的情况下,您的证书应由认证机构公司签署。在这种情况下,任何具有此类根证书列表的客户端都可以检查您的证书是否有效。然而,这项服务是有偿的,可能需要几周时间。我们可以从自签名证书开始

您可以找到生成证书的各种方法,例如:

简短摘录:

#Step 1: Generate a Private Key
openssl genrsa -des3 -out server.key 1024

#Step 2: Generate a CSR (Certificate Signing Request)
#Common Name (eg, your name or your server's hostname) []:example.com
openssl req -new -key server.key -out server.csr

#Step 3: Remove Passphrase from Key
cp server.key server.key.org
openssl rsa -in server.key.org -out server.key

#Step 4: Generating a Self-Signed Certificate
openssl x509 -req -days 365 -in server.csr -signkey server.key -out server.crt
现在有
server.key
server.crt
文件。在
启动服务器加密()之前,服务器应将这些文件传递到
QSslSocket

现在服务器可以启动SSL连接。您可以使用浏览器对其进行测试。通常,浏览器会发出连接不可信的警报。这是因为证书是自签名的,不能防止“中间人”攻击。但是,您可以要求浏览器继续该连接。因此,在服务器端,在信号
readyRead()
上有HTTP GET头

尝试将Qt客户端连接到该服务器。现在,该错误由客户端引发:

ConnectionHandler::ConnectionHandler(QString ip, int port, QObject *parent) : QObject(parent) {
//    connect(this->socket, SIGNAL(connected()), this, SLOT(connected()));
    connect(this->socket, SIGNAL(disconnected()), this, SLOT(disconnected()));
    connect(this->socket, SIGNAL(readyRead()), this, SLOT(readyRead()));
    connect(this->socket, SIGNAL(encrypted()), this, SLOT(encryptedReady()));
    connect(this->socket, SIGNAL(sslErrors(const QList<QSslError> &)), this, SLOT(SSLerrorOccured(const QList<QSslError> &)));
    connect(this->socket, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(socketError(QAbstractSocket::SocketError)));
    connect(this->socket, SIGNAL(stateChanged(QAbstractSocket::SocketState)), this, SLOT(socketStateChanged(QAbstractSocket::SocketState)));

    this->ip = ip;
    this->port = port;
}


void ConnectionHandler::socketStateChanged(QAbstractSocket::SocketState state) {
    qDebug() << state;
}


void ConnectionHandler::socketError(QAbstractSocket::SocketError) {
    qDebug() << this->socket->errorString();
}


void ConnectionHandler::encryptedReady() {
    qDebug() << "READY";

}


void ConnectionHandler::SSLerrorOccured(const QList<QSslError> &) {
    qDebug() << "EEROR";
}


void ConnectionHandler::connectToServer() {
//    this->socket->connectToHost(this->ip, this->port);
    this->socket->connectToHostEncrypted(this->ip, this->port);

    if (!this->socket->waitForConnected(5000)) {
    this->socket->close();
    this->errorMsg = this->socket->errorString();
    }
}


void ConnectionHandler::connected() {
qDebug() << "connected";
    this->connectedHostAddress = this->socket->peerAddress().toString();
    this->connectionEstablished = true;
    this->localIP = this->socket->localAddress().toString();
    this->localPort = this->socket->localPort();
} 
sslErrorOccured: ("The certificate is self-signed, and untrusted")
服务器在
error()
中说:“远程主机关闭了连接”。客户端引发了SSL证书错误,但与浏览器一样,我们可以继续该连接。放入
sslErrors()
信号处理程序:

void Client::sslErrorOccured(const QList<QSslError> & error) {
    qDebug() << "sslErrorOccured:" << error;
    socket->ignoreSslErrors(error);
}
void Client::sslerror发生(const-QList&error){
qDebug()