PySide6.QtNetwork.QDtlsClientVerifier¶
- class QDtlsClientVerifier¶
该类实现了服务器端DTLS cookie的生成和验证。More_…
概要¶
方法¶
def
__init__()def
dtlsError()def
verifiedHello()def
verifyClient()
注意
本文档可能包含从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 客户端:这意味着
QDtlsClientVerifier不会直接从套接字读取数据,而是期望应用程序读取传入的数据报,提取发送者的地址和端口,然后将这些数据传递给verifyClient()。为了发送 HelloVerifyRequest 消息,verifyClient()可以写入QUdpSocket。注意
QDtlsClientVerifier不拥有QUdpSocket对象的所有权。默认情况下,
QDtlsClientVerifier从加密强度高的伪随机数生成器中获取其密钥。注意
默认的密钥由类
QDtlsClientVerifier和QDtls的所有对象共享。由于这可能带来安全风险,RFC 6347 建议频繁更改服务器的密钥。请参阅 RFC 6347 的第 4.2.1 节,了解有关可能的服务器实现的提示。可以使用类GeneratorParameters和setCookieGeneratorParameters()来设置 Cookie 生成器参数:def updateServerSecret(self): newSecret = QByteArray(generateCryptoStrongSecret()) if newSecret.size(): usedCookies.append(newSecret) verifier.setCookieGeneratorParameters({QCryptographicHash.Sha1, newSecret})
DTLS 服务器示例展示了如何在服务器应用程序中使用
QDtlsClientVerifier。构造一个
QDtlsClientVerifier对象,parent被传递给QObject的构造函数。- cookieGeneratorParameters()¶
- Return type:
返回用于生成cookie的当前密钥和哈希算法。如果Qt配置为支持QCryptographicHash::Sha256,则默认哈希算法为QCryptographicHash::Sha256,否则为QCryptographicHash::Sha1。默认密钥是从后端特定的加密强伪随机数生成器获取的。
另请参阅
GeneratorParameterssetCookieGeneratorParameters()- dtlsError()¶
- Return type:
QDtlsError
返回发生的最后一个错误或
NoError。另请参阅
QDtlsErrordtlsErrorString()- dtlsErrorString()¶
- Return type:
字符串
返回最后一个错误的文本描述,或一个空字符串。
另请参阅
- setCookieGeneratorParameters(params)¶
- Parameters:
params –
GeneratorParameters- Return type:
布尔
从
params设置密钥和加密哈希算法。此QDtlsClientVerifier将使用这些来生成cookie。如果新密钥的大小为零,此函数返回false并且不会更改cookie生成器参数。- verifiedHello()¶
- Return type:
便利函数。返回最后一个成功验证的ClientHello消息,如果验证未完成,则返回空的QByteArray。
另请参阅
- verifyClient(socket, dgram, address, port)¶
- Parameters:
socket –
QUdpSocketdgram –
QByteArray地址 –
QHostAddressport – int
- 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¶
概要¶
方法¶
def
__init__()
注意
本文档可能包含从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:
a –
算法s –
QByteArray
从
algorithm和secret构造GeneratorParameters对象。