我正在编写代理服务器,http部分准备好了,但是在使用https时遇到了问题。 我以这种方式创建了证书和私钥(据我所知,没有它不会起作用):
OpenSSL> req-x509-newkey rsa: 2048-keyout server.key-nodes-days 365-out server.csr
我做了一个简单的QTcpServer,它将一个socketDescriptor传递给newIncomingConnection()上创建的对象。 在我的对象的构造函数中,我做了:
sock = new QSslSocket();
connect (sock,SIGNAL(readyRead()),this,SLOT(onQuery()));
connect(sock,SIGNAL(disconnected()),this,SLOT(deleteLater()));
connect(sock,SIGNAL(error(QAbstractSocket::SocketError)),this,SLOT(onError(QAbstractSocket::SocketError)));
connect(sock,SIGNAL(sslErrors(QList<QSslError>)),this,SLOT(sltSslErrors(QList<QSslError>)));
...
Load key and cert
...
sock->setProtocol(QSsl::AnyProtocol);
QSslKey sslKey(key, QSsl::Rsa);
QSslCertificate sslCert(cert);
sock->setPrivateKey(sslKey);
sock->setLocalCertificate(sslCert);
sock->setSocketDescriptor(socketDesc);
sock->startServerEncryption();
if(!sock->waitForEncrypted(30000)) {
qDebug()<<"wait for encrypted failed";
}
在控制台中连接时,我看到“等待加密失败”和套接字发出信号错误()与QAbstractSocket :: SslHandshakeFailedError。 你能否就没有错误建立ssl连接的其他方法提出建议?
答案 0 :(得分:1)
我认为您需要在致电setSocketDescriptor
和setPrivateKey
方法之前致电setLocalCertificate
。
以下是我用于创建HTTPS Server Socket
的代码,扩展了QTcpServer
。
void SslServer::incomingConnection(qintptr socketDescriptor)
{
QSslSocket *serverSocket = new QSslSocket;
if (serverSocket->setSocketDescriptor(socketDescriptor)) {
QFile keyFile(<sslKeyFileName>);
if (!keyFile.open(QIODevice::ReadOnly)) {
delete serverSocket;
return;
}
QSslKey key(&keyFile, QSsl::Rsa, QSsl::Pem, QSsl::PrivateKey);
if (key.isNull()) {
delete serverSocket;
return;
}
keyFile.close();
serverSocket->setPrivateKey(key);
// to prevent asking for client certificate.
serverSocket->setPeerVerifyMode(QSslSocket::VerifyNone);
serverSocket->setLocalCertificate(<certificateFileName>);
serverSocket->startServerEncryption();
if (serverSocket->waitForEncrypted(3000)) {
// this will emit a newConnection() signal
addPendingConnection(serverSocket);
} else {
qDebug() << "Encryption Failed.";
delete serverSocket;
}
} else {
delete serverSocket;
}
}
答案 1 :(得分:0)
请参阅sslechoserver示例的源代码。它使用的是QWebSocket,但同样适用于QSslSocket。
// Enable SSL
QSslConfiguration sslConfiguration;
QFile certFile(QStringLiteral("/home/stefan/cert/my.cert"));
QFile keyFile(QStringLiteral("/home/stefan/cert/my.key"));
certFile.open(QIODevice::ReadOnly);
keyFile.open(QIODevice::ReadOnly);
QSslCertificate certificate(&certFile, QSsl::Pem);
QSslKey sslKey(&keyFile, QSsl::Rsa, QSsl::Pem);
certFile.close();
keyFile.close();
sslConfiguration.setPeerVerifyMode(QSslSocket::VerifyNone);
sslConfiguration.setLocalCertificate(certificate);
sslConfiguration.setPrivateKey(sslKey);
sslConfiguration.setProtocol(QSsl::TlsV1SslV3);
socket.setSslConfiguration(sslConfiguration);
socket.startServerEncryption();
并且不要调用socket.waitForEncrypted(),因为这会再次导致意外错误。