QDtlsClientVerifier Class
Diese Klasse implementiert die serverseitige Generierung und Überprüfung von DTLS-Cookies. Mehr...
| Header: | #include <QDtlsClientVerifier> |
| CMake: | find_package(Qt6 REQUIRED COMPONENTS Network) target_link_libraries(mytarget PRIVATE Qt6::Network) |
| qmake: | QT += network |
| Erbt von: | QObject |
- Liste aller Mitglieder, einschließlich geerbter Mitglieder
- QDtlsClientVerifier ist Teil der Netzwerkprogrammier-API.
Öffentliche Typen
| struct | GeneratorParameters |
Öffentliche Funktionen
| QDtlsClientVerifier(QObject *parent = nullptr) | |
| virtual | ~QDtlsClientVerifier() |
| QDtlsClientVerifier::GeneratorParameters | cookieGeneratorParameters() const |
| QDtlsError | dtlsError() const |
| QString | dtlsErrorString() const |
| bool | setCookieGeneratorParameters(const QDtlsClientVerifier::GeneratorParameters ¶ms) |
| QByteArray | verifiedHello() const |
| bool | verifyClient(QUdpSocket *socket, const QByteArray &dgram, const QHostAddress &address, quint16 port) |
Ausführliche Beschreibung
Die Klasse „QDtlsClientVerifier“ implementiert die serverseitige Generierung und Überprüfung von DTLS-Cookies. Datagramm-Sicherheitsprotokolle sind in hohem Maße anfällig für eine Vielzahl von Denial-of-Service-Angriffen. Gemäß RFC 6347, Abschnitt 4.2.1, sind dies zwei der häufigsten Angriffsarten:
- Ein Angreifer sendet eine Reihe von Handshake-Initiierungsanfragen, wodurch der Server übermäßig viele Ressourcen zuweist und möglicherweise aufwendige kryptografische Operationen ausführt.
- Ein Angreifer sendet eine Reihe von Handshake-Initiierungsanfragen mit einer gefälschten Absenderadresse des Opfers, wodurch der Server als Verstärker fungiert. Normalerweise würde der Server dem Rechner des Opfers mit einer Zertifikatsnachricht antworten, die recht groß sein kann, wodurch der Rechner des Opfers mit Datagrammen überflutet wird.
Als Gegenmaßnahme gegen diese Angriffe schlägt RFC 6347, Abschnitt 4.2.1, eine zustandslose Cookie-Technik vor, die ein Server einsetzen kann:
- Als Antwort auf die anfängliche „ClientHello“-Nachricht sendet der Server eine „HelloVerifyRequest“-Nachricht, die ein Cookie enthält. Dieses Cookie ist ein kryptografischer Hash und wird unter Verwendung der Adresse des Clients, der Portnummer und des Geheimnisses des Servers (bei dem es sich um eine kryptografisch starke pseudozufällige Bytefolge handelt) generiert.
- Von einem erreichbaren DTLS-Client wird erwartet, dass er mit einer neuen „ClientHello“-Nachricht antwortet, die dieses Cookie enthält.
- Wenn der Server die „ClientHello“-Nachricht mit einem Cookie empfängt, generiert er wie oben beschrieben ein neues Cookie. Dieses neue Cookie wird mit dem in der „ClientHello“-Nachricht enthaltenen verglichen.
- Sind die Cookies identisch, wird der Client als echt angesehen, und der Server kann mit dem TLS-Handshake-Vorgang fortfahren.
Hinweis: Ein DTLS-Server ist nicht verpflichtet, DTLS-Cookies zu verwenden.
„QDtlsClientVerifier“ ist für den Einsatz in Kombination mit „ QUdpSocket “ ausgelegt, wie im folgenden Codeausschnitt gezeigt:
class DtlsServer : public QObject
{
public:
bool listen(const QHostAddress &address, quint16 port);
// ...
private:
void readyRead();
// ...
QUdpSocket serverSocket;
QDtlsClientVerifier verifier;
// ...
};
bool DtlsServer::listen(const QHostAddress &serverAddress, quint16 serverPort)
{
if (serverSocket.bind(serverAddress, serverPort))
connect(&serverSocket, &QUdpSocket::readyRead, this, &DtlsServer::readyRead);
return serverSocket.state() == QAbstractSocket::BoundState;
}
void DtlsServer::readyRead()
{
QByteArray dgram(serverSocket.pendingDatagramSize(), Qt::Uninitialized);
QHostAddress address;
quint16 port = {};
serverSocket.readDatagram(dgram.data(), dgram.size(), &address, &port);
if (verifiedClients.contains({address, port}) {
// This client was verified previously, we either continue the
// handshake or decrypt the incoming message.
} else if (verifier.verifyClient(&serverSocket, dgram, address, port)) {
// Apparently we have a real DTLS client who wants to send us
// encrypted datagrams. Remember this client as verified
// and proceed with a handshake.
} else {
// No matching cookie was found in the incoming datagram,
// verifyClient() has sent a ClientVerify message.
// We'll hear from the client again soon, if they're real.
}
}QDtlsClientVerifier schränkt die Art und Weise, wie die Anwendung „ QUdpSocket “ nutzt, in keiner Weise ein. So ist es beispielsweise möglich, dass ein Server mit einem einzigen „ QUdpSocket “ im Status „ QAbstractSocket::BoundState “ mehrere DTLS-Clients gleichzeitig bedient:
- Prüfung, ob neue Clients echte DTLS-fähige Clients sind.
- Durchführung von TLS-Handshakes mit den verifizierten Clients (siehe QDtls).
- Entschlüsseln von Datagrammen, die von den verbundenen Clients stammen (siehe QDtls).
- Versenden verschlüsselter Datagramme an die verbundenen Clients (siehe QDtls).
Dies bedeutet, dass „QDtlsClientVerifier“ nicht direkt aus einem Socket liest, sondern erwartet, dass die Anwendung ein eingehendes Datagramm liest, die Adresse und den Port des Absenders extrahiert und diese Daten anschließend an „ verifyClient()“ übergibt. Um eine „HelloVerifyRequest“-Nachricht zu senden, kann „ verifyClient()“ in „ QUdpSocket “ schreiben.
Hinweis: QDtlsClientVerifier übernimmt nicht die Eigentümerschaft am QUdpSocket -Objekt.
Standardmäßig bezieht QDtlsClientVerifier sein Geheimnis aus einem kryptografisch sicheren Pseudozufallszahlengenerator.
Hinweis: Das Standardgeheimnis wird von allen Objekten der Klassen QDtlsClientVerifier und QDtls gemeinsam genutzt. Da dies Sicherheitsrisiken mit sich bringen kann, empfiehlt RFC 6347, das Geheimnis des Servers regelmäßig zu ändern. Hinweise zu möglichen Server-Implementierungen finden Sie in RFC 6347, Abschnitt 4.2.1. Die Parameter des Cookie-Generators können mithilfe der Klassen „ QDtlsClientVerifier::GeneratorParameters “ und „ setCookieGeneratorParameters()“ festgelegt werden:
void DtlsServer::updateServerSecret()
{
const QByteArray newSecret(generateCryptoStrongSecret());
if (newSecret.size()) {
usedCookies.append(newSecret);
verifier.setCookieGeneratorParameters({QCryptographicHash::Sha1, newSecret});
}
}Das DTLS-Server-Beispiel veranschaulicht die Verwendung von `QDtlsClientVerifier` in einer Serveranwendung.
Siehe auch QUdpSocket, QAbstractSocket::BoundState, QDtls, verifyClient(), GeneratorParameters, setCookieGeneratorParameters(), cookieGeneratorParameters(), QDtls::setCookieGeneratorParameters(), QDtls::cookieGeneratorParameters(), QCryptographicHash::Algorithm, QDtlsError, dtlsError() und dtlsErrorString().
Dokumentation zu den Member-Funktionen
[explicit] QDtlsClientVerifier::QDtlsClientVerifier(QObject *parent = nullptr)
Erstellt ein `QDtlsClientVerifier`-Objekt, wobei ` parent ` an den Konstruktor von ` QObject` übergeben wird.
[virtual noexcept] QDtlsClientVerifier::~QDtlsClientVerifier()
Löscht das „ QDtlsClientVerifier “-Objekt.
QDtlsClientVerifier::GeneratorParameters QDtlsClientVerifier::cookieGeneratorParameters() const
Gibt das aktuell verwendete Geheimnis und den Hash-Algorithmus zurück, die zur Erzeugung von Cookies verwendet werden. Der Standard-Hash-Algorithmus ist „ QCryptographicHash::Sha256 “, sofern Qt für dessen Unterstützung konfiguriert wurde, andernfalls „ QCryptographicHash::Sha1 “. Das Standardgeheimnis wird aus dem backend-spezifischen, kryptografisch starken Pseudozufallszahlengenerator gewonnen.
Siehe auch QCryptographicHash::Algorithm, QDtlsClientVerifier::GeneratorParameters und setCookieGeneratorParameters().
QDtlsError QDtlsClientVerifier::dtlsError() const
Gibt den zuletzt aufgetretenen Fehler oder „ QDtlsError::NoError “ zurück.
Siehe auch „ QDtlsError “ und „ dtlsErrorString()“.
QString QDtlsClientVerifier::dtlsErrorString() const
Gibt eine textuelle Beschreibung des letzten Fehlers oder eine leere Zeichenkette zurück.
Siehe auch ` dtlsError()`.
bool QDtlsClientVerifier::setCookieGeneratorParameters(const QDtlsClientVerifier::GeneratorParameters ¶ms)
Legt das Geheimnis und den kryptografischen Hash-Algorithmus aus params fest. Dieser QDtlsClientVerifier verwendet diese Werte zur Generierung von Cookies. Wenn das neue Geheimnis die Größe Null hat, gibt diese Funktion false zurück und ändert die Parameter des Cookie-Generators nicht.
Hinweis: Der Schlüssel sollte eine kryptografisch sichere Bytefolge sein.
Siehe auch QDtlsClientVerifier::GeneratorParameters, cookieGeneratorParameters() und QCryptographicHash::Algorithm.
QByteArray QDtlsClientVerifier::verifiedHello() const
Hilfsfunktion. Gibt die zuletzt erfolgreich verifizierte „ClientHello“-Nachricht zurück oder ein leeres „ QByteArray “, falls noch keine Verifizierung abgeschlossen wurde.
Siehe auch verifyClient().
bool QDtlsClientVerifier::verifyClient(QUdpSocket *socket, const QByteArray &dgram, const QHostAddress &address, quint16 port)
socket muss ein gültiger Zeiger sein, dgram muss ein nicht leeres Datagramm sein, address darf weder null noch ein Broadcast- oder Multicast-Datagramm sein. port ist der Port des Remote-Peers. Diese Funktion gibt true zurück, wenn dgram eine ClientHello-Nachricht mit einem gültigen Cookie enthält. Wird kein passendes Cookie gefunden, sendet verifyClient() eine HelloVerifyRequest-Nachricht unter Verwendung von socket und gibt false zurück.
Der folgende Codeausschnitt zeigt, wie eine Serveranwendung auf Fehler prüfen kann:
if (!verifier.verifyClient(&socket, message, address, port)) {
switch (verifyClient.dtlsError()) {
case QDtlsError::NoError:
// Not verified yet, but no errors found and we have to wait for the next
// message from this client.
return;
case QDtlsError::TlsInitializationError:
// This error is fatal, nothing we can do about it.
// Probably, quit the server after reporting the error.
return;
case QDtlsError::UnderlyingSocketError:
// There is some problem in QUdpSocket, handle it (see QUdpSocket::error())
return;
case QDtlsError::InvalidInputParameters:
default:
Q_UNREACHABLE();
}
}Siehe auch „ QHostAddress::isNull()“, „ QHostAddress::isBroadcast()“, „ QHostAddress::isMulticast()“, „ setCookieGeneratorParameters()“ und „ cookieGeneratorParameters()“.
© 2026 The Qt Company Ltd. Documentation contributions included herein are the copyrights of their respective owners. The documentation provided herein is licensed under the terms of the GNU Free Documentation License version 1.3 as published by the Free Software Foundation. Qt and respective logos are trademarks of The Qt Company Ltd. in Finland and/or other countries worldwide. All other trademarks are property of their respective owners.