![](/img/trans.png)
[英]Can QSslSocket be used immediately after startServerEncryption()?
[英]Can't get QSslSocket to work
我試圖在Qt中編寫一個簡單的客戶端-服務器應用程序,該應用程序將通過SSL通信。 我嘗試使用QSslSockets,但是仍然遇到各種問題。
看看這個:
客戶:
#define dumpvar(x) qDebug()<<#x<<'='<<x
int main(int argc, char** argv)
{
QApplication a(argc, argv);
QSslSocket s;
auto cert = QSslCertificate::fromPath("/home/piotrek/cert.pem");
Q_ASSERT(!cert.isEmpty());
s.setCaCertificates({cert});
s.connectToHostEncrypted("localhost", 1234);
qDebug()<<"waiting for encrypted";
if (!s.waitForEncrypted(10000)){
dumpvar(s.errorString());
dumpvar(s.sslErrors());
return 0;
}
qDebug()<<"client connected";
}
服務器:
#define dumpvar(x) qDebug()<<#x<<'='<<x
class SslServer: public QTcpServer
{
// QTcpServer interface
protected:
void incomingConnection(qintptr handle) override
{
QSslSocket s;
if (!s.setSocketDescriptor(handle)){
dumpvar(s.errorString());
return;
}
s.setLocalCertificate("/home/piotrek/cert.pem");
s.setPrivateKey("/home/piotrek/pkey.pem", QSsl::Rsa, QSsl::Pem, "test");
s.startServerEncryption();
qDebug()<<"waiting for encrypted";
if(!s.waitForEncrypted(10000)){
dumpvar(s.errorString());
dumpvar(s.sslErrors());
return;
}
qDebug()<<"server encrypted";
handleConnection(&s);
}
};
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
SslServer s;
s.listen(QHostAddress::Any, 1234);
return a.exec();
}
客戶端打印:
qt.network.ssl: QSslSocket: cannot resolve SSLv2_client_method
qt.network.ssl: QSslSocket: cannot resolve SSLv2_server_method
waiting for encrypted
<10 second pause>
s.errorString() = "Network operation timed out"
s.sslErrors() = ()
服務器打印:
qt.network.ssl: QSslSocket: cannot resolve SSLv2_client_method
qt.network.ssl: QSslSocket: cannot resolve SSLv2_server_method
waiting for encrypted
<10 second pause>
s.errorString() = "The remote host closed the connection"
s.sslErrors() = (
我究竟做錯了什么?
警告的解釋是Ubuntu中的OpenSSL
編譯時沒有不安全的sslv2,但Qt 5.8嘗試在運行時加載這些功能。 Qt默認情況下僅使用安全協議,因此,除非您使用QSsl::SslV2
顯式調用QSslSocket :: setProtocol ,否則這些警告不會對您造成影響(當然,這不適用於您的openssl)。
顯然您的自簽名有問題嗎? 證書 。 此外,除非使用主機簽名不匹配,否則使用自簽名證書進行連接都會失敗。
如果您使用的是自簽名證書,則可以按照此處的說明重新生成它們。
請在下面找到工作代碼示例。 在類似環境下測試( 令人驚訝! ) Ubuntu 16.10, OpenSSL 1.0.2g 1 Mar 2016, Qt 5.8.0
。
class SslServer: public QTcpServer
{
// QTcpServer interface
protected:
void incomingConnection(qintptr handle) override
{
QSslSocket s;
if (!s.setSocketDescriptor(handle)){
dumpvar(s.errorString());
return;
}
const QString serverCertPath("/path/to/server1.pem");
const QString serverKeyPath("/path/to/server1.key");
s.setLocalCertificate(serverCertPath);
s.setPrivateKey(serverKeyPath, QSsl::Rsa, QSsl::Pem, "test");
s.startServerEncryption();
qDebug()<<"waiting for encrypted";
if(!s.waitForEncrypted(10000)){
dumpvar(s.errorString());
dumpvar(s.sslErrors());
return;
}
qDebug()<<"server encrypted";
s.write("Hello client");
s.flush();
s.waitForBytesWritten(3000);
s.close();
}
};
int main(int argc, char** argv)
{
QCoreApplication a(argc, argv);
QSslSocket s;
const QString rootCAPath("/path/to/rootCA.pem");
auto rootCACert = QSslCertificate::fromPath(rootCAPath);
Q_ASSERT(!rootCACert.isEmpty());
s.setCaCertificates(rootCACert);
// ignore SSL host name mismatch error for server certificate
QList<QSslError> errorsToIgnore;
const QString serverCertPath("/path/to/server1.pem");
auto serverCert = QSslCertificate::fromPath(serverCertPath);
Q_ASSERT(!serverCert.isEmpty());
errorsToIgnore<<QSslError(QSslError::HostNameMismatch, serverCert.at(0));
s.ignoreSslErrors(errorsToIgnore);
s.connectToHostEncrypted("localhost", 1234);
qDebug()<<"waiting for encrypted";
if (!s.waitForEncrypted(10000)){
dumpvar(s.errorString());
dumpvar(s.sslErrors());
return 0;
}
qDebug()<<"client connected";
s.waitForReadyRead(3000);
qDebug() << "Reading: " << s.bytesAvailable();
qDebug() << s.readAll();
s.close();
}
服務器輸出:
qt.network.ssl: QSslSocket: cannot resolve SSLv2_client_method
qt.network.ssl: QSslSocket: cannot resolve SSLv2_server_method
waiting for encrypted
server encrypted
客戶輸出:
qt.network.ssl: QSslSocket: cannot resolve SSLv2_client_method
qt.network.ssl: QSslSocket: cannot resolve SSLv2_server_method
waiting for encrypted
client connected
Reading: 12
"Hello client"
Press <RETURN> to close this window...
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.