PySide6.QtNetwork.QDtlsClientVerifier

class QDtlsClientVerifier

该类实现了服务器端DTLS cookie的生成和验证。More_

PySide6.QtNetwork.QDtlsClientVerifier 的继承图

概要

方法

注意

本文档可能包含从C++自动翻译到Python的代码片段。我们始终欢迎对代码片段翻译的贡献。如果您发现翻译问题,您也可以通过在我们的https:/bugreports.qt.io/projects/PYSIDE上创建工单来告知我们。

详细描述

警告

本节包含从C++自动翻译到Python的代码片段,可能包含错误。

QDtlsClientVerifier 类实现了服务器端 DTLS cookie 的生成和验证。数据报安全协议极易受到各种拒绝服务攻击。根据 RFC 6347 第 4.2.1 节,以下是两种更常见的攻击类型:

  • 攻击者传输一系列握手启动请求,导致服务器分配过多资源,并可能执行昂贵的加密操作。

  • 攻击者通过伪造受害者的源地址发送一系列握手初始化请求,使服务器充当放大器。通常,服务器会向受害机器回复一个证书消息,该消息可能非常大,从而导致受害机器被数据报淹没。

作为对这些攻击的对策,RFC 6347 第4.2.1节提出了一种服务器可以部署的无状态cookie技术:

  • 作为对初始ClientHello消息的响应,服务器发送一个HelloVerifyRequest,其中包含一个cookie。这个cookie是一个加密哈希值,是使用客户端的地址、端口号和服务器的密钥(这是一个加密强度高的伪随机字节序列)生成的。

  • 一个可达的DTLS客户端应回复一个包含此cookie的新ClientHello消息。

  • 当服务器接收到带有cookie的ClientHello消息时,它会按照上述方法生成一个新的cookie。这个新的cookie将与ClientHello消息中的cookie进行比较。

  • 在cookies相等的情况下,客户端被认为是真实的,服务器可以继续进行TLS握手过程。

注意

DTLS 服务器不需要使用 DTLS cookies。

QDtlsClientVerifier 设计用于与 QUdpSocket 配对使用,如下面的代码片段所示:

class DtlsServer(QObject):

# public
    listen = bool(QHostAddress address, quint16 port)
    # ...
# private
    def readyRead():
    # ...
    serverSocket = QUdpSocket()
    verifier = QDtlsClientVerifier()
    # ...

def listen(self, QHostAddress serverAddress, quint16 serverPort):

    if serverSocket.bind(serverAddress, serverPort):
        serverSocket.readyRead.connect(self.readyRead)
    return serverSocket.state() == QAbstractSocket.BoundState

def readyRead(self):

    dgram = QByteArray(serverSocket.pendingDatagramSize(), Qt.Uninitialized)
    address = QHostAddress()
    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.
     elif 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 不对应用程序如何使用 QUdpSocket 施加任何限制。例如,可以有一个服务器,其中只有一个 QUdpSocket 处于 BoundState 状态,同时处理多个 DTLS 客户端:

  • 测试新客户端是否真正支持DTLS。

  • 与已验证的客户端完成TLS握手(参见QDtls)。

  • 解密来自连接的客户端的数据报(参见 QDtls )。

  • 向连接的客户端发送加密的数据报(参见 QDtls )。

这意味着 QDtlsClientVerifier 不会直接从套接字读取数据,而是期望应用程序读取传入的数据报,提取发送者的地址和端口,然后将这些数据传递给 verifyClient()。为了发送 HelloVerifyRequest 消息,verifyClient() 可以写入 QUdpSocket

注意

QDtlsClientVerifier 不拥有 QUdpSocket 对象的所有权。

默认情况下,QDtlsClientVerifier 从加密强度高的伪随机数生成器中获取其密钥。

注意

默认的密钥由类 QDtlsClientVerifierQDtls 的所有对象共享。由于这可能带来安全风险,RFC 6347 建议频繁更改服务器的密钥。请参阅 RFC 6347 的第 4.2.1 节,了解有关可能的服务器实现的提示。可以使用类 GeneratorParameterssetCookieGeneratorParameters() 来设置 Cookie 生成器参数:

def updateServerSecret(self):

    newSecret = QByteArray(generateCryptoStrongSecret())
    if newSecret.size():
        usedCookies.append(newSecret)
        verifier.setCookieGeneratorParameters({QCryptographicHash.Sha1, newSecret})

DTLS 服务器示例展示了如何在服务器应用程序中使用QDtlsClientVerifier

__init__([parent=None])
Parameters:

父对象QObject

构造一个QDtlsClientVerifier对象,parent被传递给QObject的构造函数。

cookieGeneratorParameters()
Return type:

GeneratorParameters

返回用于生成cookie的当前密钥和哈希算法。如果Qt配置为支持QCryptographicHash::Sha256,则默认哈希算法为QCryptographicHash::Sha256,否则为QCryptographicHash::Sha1。默认密钥是从后端特定的加密强伪随机数生成器获取的。

另请参阅

GeneratorParameters setCookieGeneratorParameters()

dtlsError()
Return type:

QDtlsError

返回发生的最后一个错误或NoError

另请参阅

QDtlsError dtlsErrorString()

dtlsErrorString()
Return type:

字符串

返回最后一个错误的文本描述,或一个空字符串。

另请参阅

dtlsError()

setCookieGeneratorParameters(params)
Parameters:

paramsGeneratorParameters

Return type:

布尔

params设置密钥和加密哈希算法。此QDtlsClientVerifier将使用这些来生成cookie。如果新密钥的大小为零,此函数返回false并且不会更改cookie生成器参数。

注意

密钥应该是一个加密安全的字节序列。

另请参阅

GeneratorParameters cookieGeneratorParameters() Algorithm

verifiedHello()
Return type:

QByteArray

便利函数。返回最后一个成功验证的ClientHello消息,如果验证未完成,则返回空的QByteArray。

另请参阅

verifyClient()

verifyClient(socket, dgram, address, port)
Parameters:
Return type:

布尔

警告

本节包含从C++自动翻译到Python的代码片段,可能包含错误。

socket 必须是一个有效的指针,dgram 必须是一个非空的数据报,address 不能为空、广播或多播。port 是远程对等方的端口。如果 dgram 包含带有有效 cookie 的 ClientHello 消息,则此函数返回 true。如果未找到匹配的 cookie,verifyClient() 将使用 socket 发送 HelloVerifyRequest 消息并返回 false

以下代码片段展示了服务器应用程序如何检查错误:

if not verifier.verifyClient(socket, message, address, port):
    switch (verifyClient.dtlsError()) {
    elif ret == QDtlsError.NoError:
        # Not verified yet, but no errors found and we have to wait for the next
        # message from this client.
        return
    elif ret == QDtlsError.TlsInitializationError:
        # This error is fatal, nothing we can do about it.
        # Probably, quit the server after reporting the error.
        return
    elif ret == QDtlsError.UnderlyingSocketError:
        # There is some problem in QUdpSocket, handle it (see QUdpSocket::error())
        return
    elif ret == QDtlsError.InvalidInputParameters:
    else:
        Q_UNREACHABLE()
class GeneratorParameters

概要

方法

注意

本文档可能包含从C++自动翻译到Python的代码片段。我们始终欢迎对代码片段翻译的贡献。如果您发现翻译问题,您也可以通过在我们的https:/bugreports.qt.io/projects/PYSIDE上创建工单来告知我们。

详细描述

PySide6.QtNetwork.QDtlsClientVerifier.GeneratorParameters.hash
PySide6.QtNetwork.QDtlsClientVerifier.GeneratorParameters.secret
__init__()

默认构造GeneratorParameters对象,使用QCryptographicHash::Sha1作为其算法,并带有空密钥。

__init__(a, s)
Parameters:

algorithmsecret构造GeneratorParameters对象。