En esta página

QDtls Class

Esta clase proporciona encriptación para sockets UDP. Más...

Cabecera: #include <QDtls>
CMake: find_package(Qt6 REQUIRED COMPONENTS Network)
target_link_libraries(mytarget PRIVATE Qt6::Network)
qmake: QT += network
Hereda: QObject

Tipos Públicos

GeneratorParameters
enum HandshakeState { HandshakeNotStarted, HandshakeInProgress, PeerVerificationFailed, HandshakeComplete }

Funciones Públicas

QDtls(QSslSocket::SslMode mode, QObject *parent = nullptr)
virtual ~QDtls()
bool abortHandshake(QUdpSocket *socket)
QDtls::GeneratorParameters cookieGeneratorParameters() const
QByteArray decryptDatagram(QUdpSocket *socket, const QByteArray &dgram)
bool doHandshake(QUdpSocket *socket, const QByteArray &dgram = {})
QSslConfiguration dtlsConfiguration() const
QDtlsError dtlsError() const
QString dtlsErrorString() const
bool handleTimeout(QUdpSocket *socket)
QDtls::HandshakeState handshakeState() const
void ignoreVerificationErrors(const QList<QSslError> &errorsToIgnore)
bool isConnectionEncrypted() const
quint16 mtuHint() const
QHostAddress peerAddress() const
quint16 peerPort() const
QList<QSslError> peerVerificationErrors() const
QString peerVerificationName() const
bool resumeHandshake(QUdpSocket *socket)
QSslCipher sessionCipher() const
QSsl::SslProtocol sessionProtocol() const
bool setCookieGeneratorParameters(const QDtls::GeneratorParameters &params)
bool setDtlsConfiguration(const QSslConfiguration &configuration)
void setMtuHint(quint16 mtuHint)
bool setPeer(const QHostAddress &address, quint16 port, const QString &verificationName = {})
bool setPeerVerificationName(const QString &name)
bool shutdown(QUdpSocket *socket)
QSslSocket::SslMode sslMode() const
qint64 writeDatagramEncrypted(QUdpSocket *socket, const QByteArray &dgram)

Señales

void handshakeTimeout()
void pskRequired(QSslPreSharedKeyAuthenticator *authenticator)
enum class QDtlsError { NoError, InvalidInputParameters, InvalidOperation, UnderlyingSocketError, RemoteClosedConnectionError, …, TlsNonFatalError }

Descripción detallada

La clase QDtls se puede utilizar para establecer una conexión segura con un peer de red utilizando el Protocolo de Datagramas de Usuario (UDP). La conexión DTLS sobre UDP esencialmente sin conexión significa que dos peers primero tienen que completar con éxito un handshake TLS llamando a doHandshake(). Una vez completado el protocolo de enlace, se pueden enviar datagramas cifrados al par mediante writeDatagramEncrypted(). Los datagramas cifrados procedentes del par pueden descifrarse mediante decryptDatagram().

QDtls está diseñado para trabajar con QUdpSocket. Dado que QUdpSocket puede recibir datagramas procedentes de diferentes peers, una aplicación debe implementar el demultiplexado, reenviando los datagramas procedentes de diferentes peers a sus correspondientes instancias de QDtls. Se puede establecer una asociación entre un peer de red y su objeto QDtls utilizando la dirección y el número de puerto del peer. Antes de iniciar un handshake, la aplicación debe establecer la dirección y el número de puerto del peer utilizando setPeer().

QDtls no lee datagramas de QUdpSocket, esto se espera que lo haga la aplicación, por ejemplo, en un slot adjunto a la señal QUdpSocket::readyRead(). Entonces, estos datagramas deben ser procesados por QDtls.

Nota: QDtls no toma posesión del objeto QUdpSocket.

Normalmente, varios datagramas deben ser recibidos y enviados por ambos peers durante la fase de handshake. Al leer los datagramas, el servidor y el cliente deben pasar estos datagramas a doHandshake() hasta que se encuentre algún error o handshakeState() devuelva HandshakeComplete:

// A client initiates a handshake:
QUdpSocket clientSocket;
QDtls clientDtls;
clientDtls.setPeer(address, port, peerName);
clientDtls.doHandshake(&clientSocket);

// A server accepting an incoming connection; address, port, clientHello are
// read by QUdpSocket::readDatagram():
QByteArray clientHello(serverSocket.pendingDatagramSize(), Qt::Uninitialized);
QHostAddress address;
quin16 port = {};
serverSocket.readDatagram(clientHello.data(), clientHello.size(), &address, &port);

QDtls serverDtls;
serverDtls.setPeer(address, port);
serverDtls.doHandshake(&serverSocket, clientHello);

// Handshake completion, both for server and client:
void DtlsConnection::continueHandshake(const QByteArray &datagram)
{
    if (dtls.doHandshake(&udpSocket, datagram)) {
        // Check handshake status:
        if (dtls.handshakeStatus() == QDlts::HandshakeComplete) {
            // Secure DTLS connection is now established.
        }
    } else {
        // Error handling.
    }
}

Para un servidor, la primera llamada a doHandshake() requiere un datagrama no vacío que contenga un mensaje ClientHello. Si el servidor también despliega QDtlsClientVerifier, se espera que el primer mensaje ClientHello sea el verificado por QDtlsClientVerifier.

En caso de que la identidad del peer no pueda ser validada durante el handshake, la aplicación debe inspeccionar los errores devueltos por peerVerificationErrors() y entonces ignorar los errores llamando a ignoreVerificationErrors() o abortar el handshake llamando a abortHandshake(). Si los errores fueron ignorados, el handshake puede ser reanudado llamando a resumeHandshake().

Una vez completado el handshake, se pueden enviar y recibir datagramas de forma segura:

// Sending an encrypted datagram:
dtlsConnection.writeDatagramEncrypted(&clientSocket, "Hello DTLS server!");

// Decryption:
QByteArray encryptedMessage(dgramSize);
socket.readDatagram(encryptedMessage.data(), dgramSize);
const QByteArray plainText = dtlsConnection.decryptDatagram(&socket, encryptedMessage);

Una conexión DTLS puede cerrarse utilizando shutdown().

DtlsClient::~DtlsClient()
{
    clientDtls.shutdown(&clientSocket);
}

Advertencia: Se recomienda llamar a shutdown() antes de destruir el objeto QDtls del cliente si está planeando reutilizar el mismo número de puerto para conectarse al servidor más tarde. De lo contrario, el servidor puede perder los mensajes ClientHello entrantes, vea RFC 6347, sección 4.2.8 para más detalles y consejos de implementación.

Si el servidor no utiliza QDtlsClientVerifier, debe configurar sus objetos QDtls para desactivar el procedimiento de verificación de cookies:

auto config = QSslConfiguration::defaultDtlsConfiguration();
config.setDtlsCookieVerificationEnabled(false);
// Some other customization ...
dtlsConnection.setDtlsConfiguration(config);

Un servidor que utilice la verificación de cookies con parámetros generadores no predeterminados debe configurar los mismos parámetros para su objeto QDtls antes de iniciar el handshake.

Nota: El protocolo DTLS deja el descubrimiento de la Unidad de Transmisión Máxima de Ruta (PMTU) a la aplicación. La aplicación puede proporcionar a QDtls la MTU utilizando setMtuHint(). Esta sugerencia sólo afecta a la fase de handshake, ya que sólo los mensajes de handshake pueden ser fragmentados y reensamblados por el DTLS. Todos los demás mensajes enviados por la aplicación deben caber en un único datagrama.

Nota: Las cabeceras específicas del DTLS añaden cierta sobrecarga a los datos de la aplicación, reduciendo aún más el tamaño posible del mensaje.

Advertencia: Un servidor configurado para responder con HelloVerifyRequest descartará todos los mensajes ClientHello fragmentados, sin iniciar nunca un handshake.

Los ejemplos de servidor DTLS y cliente DTLS ilustran cómo utilizar QDtls en aplicaciones.

Ver también QUdpSocket, QDtlsClientVerifier, HandshakeState, QDtlsError, y QSslConfiguration.

Documentación de tipos de miembros

[alias] QDtls::GeneratorParameters

enum QDtls::HandshakeState

Describe el estado actual del handshake DTLS.

Este enum describe el estado actual del handshake DTLS para una conexión QDtls.

ConstanteValorDescripción
QDtls::HandshakeNotStarted0Aún no se ha hecho nada.
QDtls::HandshakeInProgress1Se ha iniciado el handshake y no se han encontrado errores hasta el momento.
QDtls::PeerVerificationFailed2No se puede establecer la identidad del peer.
QDtls::HandshakeComplete3El Handshake se completó con éxito y se estableció la conexión cifrada.

Véase también QDtls::doHandshake() y QDtls::handshakeState().

Documentación de las funciones miembro

[explicit] QDtls::QDtls(QSslSocket::SslMode mode, QObject *parent = nullptr)

Crea un objeto QDtls, parent se pasa al constructor QObject. mode es QSslSocket::SslServerMode para una conexión DTLS del lado del servidor o QSslSocket::SslClientMode para un cliente.

Véase también sslMode() y QSslSocket::SslMode.

[virtual noexcept] QDtls::~QDtls()

Destruye el objeto QDtls.

bool QDtls::abortHandshake(QUdpSocket *socket)

Aborta el handshake en curso. Devuelve true si había uno en curso en socket; en caso contrario, establece un error adecuado y devuelve false.

Véase también doHandshake() y resumeHandshake().

QDtls::GeneratorParameters QDtls::cookieGeneratorParameters() const

Devuelve el algoritmo hash y el secreto actuales, ya sean los predeterminados o los establecidos previamente mediante una llamada a setCookieGeneratorParameters().

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 QDtlsClientVerifier y setCookieGeneratorParameters().

QByteArray QDtls::decryptDatagram(QUdpSocket *socket, const QByteArray &dgram)

Desencripta dgram y devuelve su contenido como texto sin formato. El handshake debe completarse antes de que los datagramas puedan ser desencriptados. Dependiendo del tipo de mensaje TLS, la conexión puede escribir en socket, que debe ser un puntero válido.

bool QDtls::doHandshake(QUdpSocket *socket, const QByteArray &dgram = {})

Inicia o continúa un handshake DTLS. socket debe ser un puntero válido. Cuando se inicia un handshake DTLS del lado del servidor, dgram debe contener el mensaje ClientHello inicial leído de QUdpSocket. Esta función devuelve true si no se encontró ningún error. El estado del Handshake puede comprobarse utilizando handshakeState(). El retorno de false significa que se ha producido algún error, utilice dtlsError() para obtener información más detallada.

Nota: Si no se puede establecer la identidad del peer, el error se establece en QDtlsError::PeerVerificationError. Si se desea ignorar los errores de verificación y continuar la conexión, se debe llamar a ignoreVerificationErrors() y luego a resumeHandshake(). Si no se pueden ignorar los errores, se debe llamar a abortHandshake().

if (!dtls.doHandshake(&socket, dgram)) {
    if (dtls.dtlsError() == QDtlsError::PeerVerificationError)
        dtls.abortAfterError(&socket);
}

Véase también handshakeState(), dtlsError(), ignoreVerificationErrors(), resumeHandshake() y abortHandshake().

QSslConfiguration QDtls::dtlsConfiguration() const

Devuelve la configuración DTLS por defecto o la configuración establecida por una llamada anterior a setDtlsConfiguration().

Véase también setDtlsConfiguration() y QSslConfiguration::defaultDtlsConfiguration().

QDtlsError QDtls::dtlsError() const

Devuelve el último error encontrado por la conexión o QDtlsError::NoError.

Véase también dtlsErrorString() y QDtlsError.

QString QDtls::dtlsErrorString() const

Devuelve una descripción textual del último error encontrado por la conexión o una cadena vacía.

Véase también dtlsError().

bool QDtls::handleTimeout(QUdpSocket *socket)

Si se produce un timeout durante el handshake, se emite la señal handshakeTimeout(). La aplicación debe llamar a handleTimeout() para retransmitir los mensajes de handshake; handleTimeout() devuelve true si se ha producido un timeout, false en caso contrario. socket debe ser un puntero válido.

Véase también handshakeTimeout().

QDtls::HandshakeState QDtls::handshakeState() const

Devuelve el estado actual del apretón de manos para este QDtls.

Véase también doHandshake() y QDtls::HandshakeState.

[signal] void QDtls::handshakeTimeout()

La pérdida de paquetes puede provocar tiempos de espera durante la fase de handshake. En este caso QDtls emite una señal handshakeTimeout(). Llama a handleTimeout() para retransmitir los mensajes de handshake:

DtlsClient::DtlsClient()
{
    // Some initialization code here ...
    connect(&clientDtls, &QDtls::handshakeTimeout, this, &DtlsClient::handleTimeout);
}

void DtlsClient::handleTimeout()
{
    clientDtls.handleTimeout(&clientSocket);
}

Véase también handleTimeout().

void QDtls::ignoreVerificationErrors(const QList<QSslError> &errorsToIgnore)

Este método indica a QDtls que ignore sólo los errores indicados en errorsToIgnore.

Si, por ejemplo, quieres conectarte a un servidor que utiliza un certificado autofirmado, considera el siguiente fragmento:

QList<QSslCertificate> cert = QSslCertificate::fromPath("server-certificate.pem"_L1);
QSslError error(QSslError::SelfSignedCertificate, cert.at(0));
QList<QSslError> expectedSslErrors;
expectedSslErrors.append(error);

QDtls dtls;
dtls.ignoreVerificationErrors(expectedSslErrors);
dtls.doHandshake(udpSocket);

También puedes llamar a esta función después de que doHandshake() encuentre el error QDtlsError::PeerVerificationError, y luego reanudar el handshake llamando a resumeHandshake().

Las llamadas posteriores a esta función reemplazarán la lista de errores que se pasaron en las llamadas anteriores. Puede borrar la lista de errores que desea ignorar llamando a esta función con una lista vacía.

Véase también doHandshake(), resumeHandshake(), y QSslError.

bool QDtls::isConnectionEncrypted() const

Devuelve true si el handshake DTLS se ha completado con éxito.

Véase también doHandshake() y handshakeState().

quint16 QDtls::mtuHint() const

Devuelve el valor establecido previamente por setMtuHint(). El valor por defecto es 0.

Véase también setMtuHint().

QHostAddress QDtls::peerAddress() const

Devuelve la dirección del par, establecida por setPeer(), o QHostAddress::Null.

Véase también setPeer().

quint16 QDtls::peerPort() const

Devuelve el número de puerto del peer, establecido por setPeer(), o 0.

Véase también setPeer().

QList<QSslError> QDtls::peerVerificationErrors() const

Devuelve los errores encontrados al establecer la identidad del peer.

Si desea continuar la conexión a pesar de los errores producidos, debe llamar a ignoreVerificationErrors().

QString QDtls::peerVerificationName() const

Devuelve el nombre de host establecido por setPeer() o setPeerVerificationName(). El valor por defecto es una cadena vacía.

Véase también setPeerVerificationName() y setPeer().

[signal] void QDtls::pskRequired(QSslPreSharedKeyAuthenticator *authenticator)

QDtls emite esta señal cuando negocia un cifrado PSK, por lo que se requiere una autenticación PSK.

Cuando se utiliza PSK, el cliente debe enviar al servidor una identidad válida y una clave precompartida válida, para que el handshake TLS pueda continuar. Las aplicaciones pueden proporcionar esta información en una ranura conectada a esta señal, rellenando el objeto authenticator pasado según sus necesidades.

Nota: Ignorar esta señal, o no proporcionar las credenciales requeridas, causará que el handshake falle, y por lo tanto que la conexión sea abortada.

Nota: El objeto authenticator es propiedad de QDtls y no debe ser eliminado por la aplicación.

Véase también QSslPreSharedKeyAuthenticator.

bool QDtls::resumeHandshake(QUdpSocket *socket)

Si se ignoraron los errores de verificación de pares durante el handshake, resumeHandshake() reanuda y completa el handshake y devuelve true. socket debe ser un puntero válido. Devuelve false si no se ha podido reanudar el handshake.

Véase también doHandshake(), abortHandshake(), peerVerificationErrors() y ignoreVerificationErrors().

QSslCipher QDtls::sessionCipher() const

Devuelve el cipher criptográfico utilizado por esta conexión, o un cifrado nulo si la conexión no está cifrada. El cifrado para la sesión se selecciona durante la fase de apretón de manos. El cifrado se utiliza para cifrar y descifrar datos.

QSslConfiguration proporciona funciones para establecer la lista ordenada de cifradores a partir de la cual la fase de handshake seleccionará finalmente el cifrado de la sesión. Esta lista ordenada debe estar en su lugar antes de que comience la fase de handshake.

Véase también QSslConfiguration, setDtlsConfiguration(), y dtlsConfiguration().

QSsl::SslProtocol QDtls::sessionProtocol() const

Devuelve la versión del protocolo DTLS utilizada por esta conexión, o UnknownProtocol si la conexión aún no está cifrada. El protocolo para la conexión se selecciona durante la fase de handshake.

setDtlsConfiguration() puede establecer la versión preferida antes de que comience el handshake.

Véase también setDtlsConfiguration(), QSslConfiguration, QSslConfiguration::defaultDtlsConfiguration(), y QSslConfiguration::setProtocol().

bool QDtls::setCookieGeneratorParameters(const QDtls::GeneratorParameters &params)

Establece el algoritmo hash criptográfico y el secreto de params. Esta función sólo es necesaria para una conexión del lado del servidor QDtls. Devuelve true si tiene éxito.

Nota: Esta función debe ser llamada antes de que comience el handshake.

Véase también cookieGeneratorParameters(), doHandshake(), QDtlsClientVerifier, y QDtlsClientVerifier::cookieGeneratorParameters().

bool QDtls::setDtlsConfiguration(const QSslConfiguration &configuration)

Establece la configuración TLS de la conexión desde configuration y devuelve true si tiene éxito.

Nota: Esta función debe ser llamada antes de que comience el handshake.

Véase también dtlsConfiguration() y doHandshake().

void QDtls::setMtuHint(quint16 mtuHint)

mtuHint es la unidad de transmisión máxima (MTU), descubierta o adivinada por la aplicación. No es necesario que la aplicación establezca este valor.

Véase también mtuHint() y QAbstractSocket::PathMtuSocketOption.

bool QDtls::setPeer(const QHostAddress &address, quint16 port, const QString &verificationName = {})

Establece la dirección del homólogo, port, y el nombre de host y devuelve true si se ha realizado correctamente. address no debe ser nulo, multidifusión ni difusión. verificationName es el nombre de host utilizado para la validación del certificado.

Véase también peerAddress(), peerPort() y peerVerificationName().

bool QDtls::setPeerVerificationName(const QString &name)

Establece el host name que se utilizará para la validación del certificado y devuelve true si tiene éxito.

Nota: Esta función debe ser llamada antes de que comience el handshake.

Véase también peerVerificationName() y setPeer().

bool QDtls::shutdown(QUdpSocket *socket)

Envía un mensaje de alerta de cierre cifrado y cierra la conexión DTLS. El estado de Handshake cambia a QDtls::HandshakeNotStarted. socket debe ser un puntero válido. Esta función devuelve true en caso de éxito.

Véase también doHandshake().

QSslSocket::SslMode QDtls::sslMode() const

Devuelve QSslSocket::SslServerMode para una conexión del lado del servidor y QSslSocket::SslClientMode para un cliente.

Véase también QDtls() y QSslSocket::SslMode.

qint64 QDtls::writeDatagramEncrypted(QUdpSocket *socket, const QByteArray &dgram)

Cifra dgram y escribe los datos cifrados en socket. Devuelve el número de bytes escritos, o -1 en caso de error. El handshake debe completarse antes de escribir los datos encriptados. socket debe ser un puntero válido.

Véase también doHandshake(), handshakeState(), isConnectionEncrypted(), y dtlsError().

No miembros relacionados

enum class QDtlsError

Describe los errores que pueden encontrar los objetos de las clases QDtls y QDtlsClientVerifier.

Este enum describe los errores generales y específicos de TLS que pueden encontrar los objetos de las clases QDtlsClientVerifier y QDtls.

ConstanteValorDescripción
QDtls::QDtlsError::NoError0No se ha producido ningún error, la última operación se ha realizado correctamente.
QDtls::QDtlsError::InvalidInputParameters1Los parámetros de entrada proporcionados por el autor de la llamada no eran válidos.
QDtls::QDtlsError::InvalidOperation2Se intentó realizar una operación en un estado que no lo permitía.
QDtls::QDtlsError::UnderlyingSocketError3QUdpSocket::writeDatagram() falló, QUdpSocket::error() y QUdpSocket::errorString() pueden proporcionar información más específica.
QDtls::QDtlsError::RemoteClosedConnectionError4Se recibió un mensaje de alerta de desconexión TLS.
QDtls::QDtlsError::PeerVerificationError5No se pudo verificar la identidad del peer durante el handshake TLS.
QDtls::QDtlsError::TlsInitializationError6Se produjo un error al inicializar un backend TLS subyacente.
QDtls::QDtlsError::TlsFatalError7Se ha producido un error fatal durante el protocolo TLS, distinto de un error de verificación de pares o un error de inicialización de TLS.
QDtls::QDtlsError::TlsNonFatalError8Un fallo al cifrar o descifrar un datagrama, no fatal, lo que significa que QDtls puede seguir funcionando después de este error.

© 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.