- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
我有一个使用QTcpSocket
的客户端-服务器应用程序。现在我想改用加密的 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();
}
这里是服务器端的:
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::HostLookupState
QAbstractSocket::ConnectingState
QAbstractSocket::ConnectedState
"The remote host closed the connection"
QAbstractSocket::ClosingState
QAbstractSocket::UnconnectedState
对于服务器:
QAbstractSocket::ConnectedState
"Error during SSL handshake: error:1408A0C1:SSL routines:SSL3_GET_CLIENT_HELLO:no shared cipher"
QAbstractSocket::UnconnectedState
有人知道如何解决这个问题吗?
最佳答案
我假设使用非加密套接字一切都很好。因此,让我们只关注使用 QSslSocket
进行详细说明的特殊性。如果需要,我可以分享更大的部分或工作代码。还有一个关于 SSL 证书的大故事,我将在这里简要介绍一下。
首先让我们在一些外部 HTTP SSL 服务器上检查您的客户端,例如:
socket->connectToHostEncrypted("gmail.com", 443);
它应该可以立即使用默认的 SSL 协议(protocol)(没有任何 setProtocol()
)。在 encrypted()
信号上,您可以编写 HTTP GET header ,在 readyRead()
上,将收到回复。
现在尝试为 "gmail.com"
设置 socket->setProtocol(QSsl::SslV3);
。预期结果:
sslErrorOccured: ("The host name did not match any of the valid hosts for this certificate")
请注意,它不是 error()
信号,而是 sslErrors()
信号,用于通知客户端可以忽略的证书问题。
因此,为简单起见,让我们使用默认的 SSL 协议(protocol),而不使用 setProtocol()
。
由于客户端处于工作状态,我们可以转到服务器。您在第一级 SSL 认证挑战中被打扰了。要通过服务器开始初始化 SSL 连接,您必须至少提供私有(private)加密 key 和公共(public)证书。那是你的错误:
"Error during SSL handshake: error:1408A0C1:SSL routines:SSL3_GET_CLIENT_HELLO:no shared cipher"
在完美的情况下,您的证书应该由认证机构公司签署。在这种情况下,任何拥有此类根证书列表的客户端都能够检查您的证书是否有效。然而,该服务是有偿的,可能需要几周时间。我们可以从自签名证书开始。
您可以找到各种生成证书的方法,例如:"How to create a self-signed SSL Certificate which can be used for testing purposes or internal usage"
简短摘录:
#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
文件。服务器应在 startServerEncryption()
之前将这些文件传递给 QSslSocket
:
socket->setPrivateKey("c:/test/ssl/cert/server.key", QSsl::Rsa);
socket->setLocalCertificate("c:/test/ssl/cert/server.crt");
现在服务器可以开始SSL连接了。你可以用浏览器测试一下。通常浏览器会发出连接不可信的警报。那是因为证书是自签名的,它不能防止“中间人”攻击。但是,您可以要求浏览器继续该连接。因此,在服务器端,您将在信号 readyRead()
上拥有 HTTP GET header 。
尝试将 Qt 客户端连接到该服务器。现在错误是由客户端引发的:
sslErrorOccured: ("The certificate is self-signed, and untrusted")
服务器在 error()
中说:“远程主机关闭了连接”。客户端引发了 SSL 证书错误,但与浏览器一样,我们可以继续该连接。放socket->ignoreSslErrors()
在 sslErrors()
信号处理程序中:
void Client::sslErrorOccured(const QList<QSslError> & error) {
qDebug() << "sslErrorOccured:" << error;
socket->ignoreSslErrors(error);
}
就是这样。当然,您的客户端不应该接受来自所有服务器的所有 SSL 证书错误,因为此类错误意味着连接并不真正安全并且可能被黑客入侵。它仅用于测试。 QSslError
对象包含证书数据,因此您的客户端可能只接受来自服务器的一个特定的自签名证书,而忽略所有其他此类错误。也可以创建您自己的“权威根证书”,您可以手动将其写入系统。然后该证书可用于签署您的服务器证书。您的客户端会认为这是可信连接,因为它将能够通过系统根证书对其进行验证。
请注意,OpenSSL 库也可能存在一些问题。在 Linux 或 OS X 上,OpenSSL 处于默认设置,但对于 Windows,应手动安装。 Windows 系统 PATH
中可能已经存在一些 OpenSSL 编译,例如 CMake 有一些有限的 OpenSSL 库。但是,一般来说,对于 Windows,您应该将 OpenSSL 与您的应用程序一起部署。
关于带有 QSslSocket 的 Qt 连接不正确,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33198360/
在 Windows 7 Ultimate x64 上的 Qt 4.8 中,当我尝试使用 QNetworkAccessManager 通过网络进行 post() 操作时: _net_acc_mgr.po
我正在使用 Qt Creator 4.2.0 运行 Qt 5.7.1(MSVC 2015,32 位)。 QSslSocket 有问题。我收到以下错误: qt.network.ssl: QSslSock
我在 debian wheezy 中使用 Qt 5.4.1 中的 QSslSocket 创建了一个 sslclient 和 sslserver。当我运行程序时,它们根本不工作。调试我的代码后,我看到它
在我的项目中,我需要使用特定版本的 OpenSSL。我同时使用 Qt 4.8.6 和 Qt 5.4.0。我想创建一个自定义 QSslSocket 以传递给 QNetworkAccessManager,
我正在尝试用 Qt 编写一个简单的客户端-服务器应用程序,该应用程序将通过 SSL 进行通信。我尝试使用 QSslSockets,但我一直遇到各种问题。 看看这个: 客户: #define dumpv
我有一个客户端程序和一个服务器程序,它们使用 QSslSockets 进行通信。在服务器程序中,如果客户端成功连接,我将发送一个字符串 "Snameadded",我还想向它发送服务器上的用户列表,但作
这是我编写的同步 TCP 客户端中 read() 语句上方的一小段代码。 std::cout bytesAvailable() waitForReadyRead(); std::cou
我有一个使用QTcpSocket 的客户端-服务器应用程序。现在我想改用加密的 SSL 连接,因此我尝试切换到 QSslSocket。但是我无法与服务器建立连接。这是客户端的代码: Connectio
我正在尝试使用 Qt 文档中的示例代码实现 SSL 服务器。 但是在 serverSocket->startServerEncryption(); 被调用之后,什么也没有发生——无论是 encrypt
是否可以创建一个新的 QSslSocket 并让它获得现有 TCP 连接的所有权,并丢弃旧的 QTcpSocket,而不中断或关闭 TCP 连接? 我需要它在我的 FTP 服务器中实现显式 FTPS,
我使用此代码通过套接字传输大文件内存使用量没有峰值: connect(socket, SIGNAL(bytesWritten(qint64)), this, SLOT(refillSocket
我真的很困惑,希望有人知道我的问题。 我有一个非常简单的 SSL 客户端和服务器。连接很好。沟通很好。当客户端与服务器断开连接时,就会出现问题。这会在服务器上触发一个信号,该信号在 SLOT erro
我对 wkhtmltopdf 有疑问。我在我的 docker 中使用了这样的 wkhtmltopdf。 wkhtmltopdf https://www.google.com google.pdf 然后
我正在编写代理服务器,http 部分已准备就绪,但 https 有问题。我以这种方式创建了一个证书和私钥(据我所知,没有它是行不通的): OpenSSL> req-x509-newkey rsa: 2
我正在尝试通过 SSL 连接到 Twitch 聊天服务器,我基本上复制并粘贴了 QT 中安全 SSL 连接示例中的一些代码。当我可以 connectToHostEncrypted 时,一切都崩溃了。非
我们的业务应用程序基于 Qt 的生产服务器出现问题。当 SSL 连接总数随时间增加时,一些客户端根本无法连接。 QSslSocket::waitForEncrypted() 开始失败,没有 QSslE
需要创建一个使用 SSL 连接到客户端的小型服务器应用程序。一次只能连接一个客户端。 每次客户端尝试建立新连接时,都会调用以下函数: void Control::on_newConnection()
我有一个应用程序作为代理使用 QTcpSocket 拦截 HTTP 请求。我正在尝试将其扩展为也适用于 HTTPS,但它似乎并没有像我预期的那样工作。由于应用程序的独特性,我无法使用 QHttp。 目
我正在 Windows 上开发一个应连接到服务器的应用程序。因此我实现了一个 QSslSocket。 执行连接方法后,sslSocket errorString 发送 The issuer certi
有一个定义 QT_NO_SSL ,如果没有找到 Ssl 库,则定义。还有方法 QSslSocket::supportsSsl() . 但这两者有什么关系,它们是等价的吗?是否QT_NO_SSL QS
我是一名优秀的程序员,十分优秀!