QDtlsClientVerifier Class
Esta clase implementa la generación y verificación de cookies DTLS del lado del servidor. Más...
| Cabecera: | #include <QDtlsClientVerifier> |
| CMake: | find_package(Qt6 REQUIRED COMPONENTS Network)target_link_libraries(mytarget PRIVATE Qt6::Network) |
| qmake: | QT += network |
| Hereda: | QObject |
- Lista de todos los miembros, incluyendo los heredados
- QDtlsClientVerifier es parte de la API de programación de red.
Tipos Públicos
| struct | GeneratorParameters |
Funciones Públicas
| 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) |
Descripción detallada
La clase QDtlsClientVerifier implementa la generación y verificación de cookies DTLS del lado del servidor. Los protocolos de seguridad de datagramas son altamente susceptibles a una variedad de ataques de Denegación de Servicio. Según el RFC 6347, sección 4.2.1, estos son dos de los tipos de ataque más comunes:
- Un atacante transmite una serie de peticiones de iniciación de handshake, provocando que un servidor asigne recursos excesivos y potencialmente realice costosas operaciones criptográficas.
- Un atacante transmite una serie de peticiones de inicio de apretón de manos con una fuente falsificada de la víctima, haciendo que el servidor actúe como amplificador. Normalmente, el servidor respondería a la máquina víctima con un mensaje de certificado, que puede ser bastante grande, inundando así la máquina víctima con datagramas.
Como contramedida a estos ataques, el RFC 6347, sección 4.2.1 propone una técnica de cookies sin estado que un servidor puede desplegar:
- En respuesta al mensaje inicial ClientHello, el servidor envía un HelloVerifyRequest, que contiene una cookie. Esta cookie es un hash criptográfico y se genera utilizando la dirección del cliente, el número de puerto y el secreto del servidor (que es una secuencia de bytes pseudoaleatoria criptográficamente fuerte).
- Se espera que un cliente DTLS alcanzable responda con un nuevo mensaje ClientHello que contenga esta cookie.
- Cuando el servidor recibe el mensaje ClientHello con una cookie, genera una nueva cookie como se ha descrito anteriormente. Esta nueva cookie se compara con la que se encuentra en el mensaje ClientHello.
- En las cookies son iguales, se considera que el cliente es real, y el servidor puede continuar con un procedimiento de handshake TLS.
Nota: No es necesario que un servidor DTLS utilice cookies DTLS.
QDtlsClientVerifier está diseñado para trabajar en pareja con QUdpSocket, como se muestra en el siguiente extracto de código:
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 no impone ninguna restricción sobre cómo la aplicación utiliza QUdpSocket. Por ejemplo, es posible tener un servidor con un único QUdpSocket en estado QAbstractSocket::BoundState, manejando múltiples clientes DTLS simultáneamente:
- Comprobación de si los nuevos clientes son clientes DTLS reales.
- Completar los handshakes TLS con los clientes verificados (ver QDtls).
- Descifrar los datagramas procedentes de los clientes conectados (véase QDtls).
- Enviar datagramas encriptados a los clientes conectados (ver QDtls).
Esto implica que QDtlsClientVerifier no lee directamente de un socket, en su lugar espera que la aplicación lea un datagrama entrante, extraiga la dirección del remitente, y el puerto, y luego pase estos datos a verifyClient(). Para enviar un mensaje HelloVerifyRequest, verifyClient() puede escribir en el QUdpSocket.
Nota: QDtlsClientVerifier no toma propiedad del objeto QUdpSocket.
Por defecto QDtlsClientVerifier obtiene su secreto de un generador de números pseudoaleatorios criptográficamente fuerte.
Nota: El secreto por defecto es compartido por todos los objetos de las clases QDtlsClientVerifier y QDtls. Dado que esto puede suponer riesgos de seguridad, el RFC 6347 recomienda cambiar el secreto del servidor con frecuencia. Por favor, vea RFC 6347, sección 4.2.1 para pistas sobre posibles implementaciones del servidor. Los parámetros del generador de cookies pueden establecerse utilizando la clase QDtlsClientVerifier::GeneratorParameters y setCookieGeneratorParameters():
void DtlsServer::updateServerSecret() { const QByteArray newSecret(generateCryptoStrongSecret()); if (newSecret.size()) { usedCookies.append(newSecret); verifier.setCookieGeneratorParameters({QCryptographicHash::Sha1, newSecret}); } }
El ejemplo de servidor DTLS ilustra cómo utilizar QDtlsClientVerifier en una aplicación de servidor.
Ver también QUdpSocket, QAbstractSocket::BoundState, QDtls, verifyClient(), GeneratorParameters, setCookieGeneratorParameters(), cookieGeneratorParameters(), QDtls::setCookieGeneratorParameters(), QDtls::cookieGeneratorParameters(), QCryptographicHash::Algorithm, QDtlsError, dtlsError(), y dtlsErrorString().
Documentación de las funciones miembro
[explicit] QDtlsClientVerifier::QDtlsClientVerifier(QObject *parent = nullptr)
Construye un objeto QDtlsClientVerifier, parent se pasa al constructor de QObject.
[virtual noexcept] QDtlsClientVerifier::~QDtlsClientVerifier()
Destruye el objeto QDtlsClientVerifier.
QDtlsClientVerifier::GeneratorParameters QDtlsClientVerifier::cookieGeneratorParameters() const
Devuelve el secreto actual y el algoritmo hash utilizado para generar cookies. El algoritmo hash por defecto es QCryptographicHash::Sha256 si Qt fue configurado para soportarlo, QCryptographicHash::Sha1 en caso contrario. El secreto por defecto se obtiene del generador de números pseudoaleatorios criptográficamente fuerte específico del backend.
Véase también QCryptographicHash::Algorithm, QDtlsClientVerifier::GeneratorParameters, y setCookieGeneratorParameters().
QDtlsError QDtlsClientVerifier::dtlsError() const
Devuelve el último error producido o QDtlsError::NoError.
Véase también QDtlsError y dtlsErrorString().
QString QDtlsClientVerifier::dtlsErrorString() const
Devuelve una descripción textual del último error, o una cadena vacía.
Véase también dtlsError().
bool QDtlsClientVerifier::setCookieGeneratorParameters(const QDtlsClientVerifier::GeneratorParameters ¶ms)
Establece el secreto y el algoritmo hash criptográfico de params. Este QDtlsClientVerifier los utilizará para generar cookies. Si el nuevo secreto tiene tamaño cero, esta función devuelve false y no cambia los parámetros del generador de cookies.
Nota: Se supone que el secreto es una secuencia de bytes criptográficamente segura.
Ver también QDtlsClientVerifier::GeneratorParameters, cookieGeneratorParameters(), y QCryptographicHash::Algorithm.
QByteArray QDtlsClientVerifier::verifiedHello() const
Función de conveniencia. Devuelve el último mensaje ClientHello verificado con éxito, o un QByteArray vacío si no se ha completado ninguna verificación.
Véase también verifyClient().
bool QDtlsClientVerifier::verifyClient(QUdpSocket *socket, const QByteArray &dgram, const QHostAddress &address, quint16 port)
socket debe ser un puntero válido, dgram debe ser un datagrama no vacío, address no puede ser nulo, broadcast o multicast. port es el puerto del par remoto. Esta función devuelve true si dgram contiene un mensaje ClientHello con una cookie válida. Si no se encuentra ninguna cookie que coincida, verifyClient() enviará un mensaje HelloVerifyRequest utilizando socket y devolverá false.
El siguiente fragmento muestra cómo una aplicación de servidor puede comprobar si hay errores:
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(); } }
Véase también QHostAddress::isNull(), QHostAddress::isBroadcast(), QHostAddress::isMulticast(), setCookieGeneratorParameters(), y 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.