PySide6.QtNetwork.QDtls

class QDtls

该类为UDP套接字提供加密。更多

PySide6.QtNetwork.QDtls 的继承图

概要

方法

信号

注意

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

详细描述

警告

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

QDtls 类可用于通过用户数据报协议(UDP)与网络对等方建立安全连接。基于本质上无连接的UDP的DTLS连接意味着两个对等方首先必须通过调用doHandshake()成功完成TLS握手。握手完成后,可以使用writeDatagramEncrypted()向对等方发送加密的数据报。来自对等方的加密数据报可以通过decryptDatagram()进行解密。

QDtls 设计用于与 QUdpSocket 一起工作。由于 QUdpSocket 可以接收来自不同对等方的数据报,应用程序必须实现解复用,将来自不同对等方的数据报转发到它们对应的 QDtls 实例。可以使用对等方的地址和端口号建立网络对等方与其 QDtls 对象之间的关联。在开始握手之前,应用程序必须使用 setPeer() 设置对等方的地址和端口号。

QDtls 不会从 QUdpSocket 读取数据报,这通常由应用程序完成,例如,在连接到 QUdpSocket::readyRead() 信号的槽中。然后,这些数据报必须由 QDtls 处理。

注意

QDtls 不会获取 QUdpSocket 对象的所有权。

通常,在握手阶段,双方都会接收和发送多个数据报。在读取数据报时,服务器和客户端必须将这些数据报传递给doHandshake(),直到发现某些错误或handshakeState()返回HandshakeComplete

# A client initiates a handshake:
clientSocket = QUdpSocket()
clientDtls = QDtls()
clientDtls.setPeer(address, port, peerName)
clientDtls.doHandshake(clientSocket)
# A server accepting an incoming connection; address, port, clientHello are
# read by QUdpSocket::readDatagram():
clientHello = QByteArray(serverSocket.pendingDatagramSize(), Qt.Uninitialized)
address = QHostAddress()
port = {}
serverSocket.readDatagram(clientHello.data(), clientHello.size(), address, port)
serverDtls = QDtls()
serverDtls.setPeer(address, port)
serverDtls.doHandshake(serverSocket, clientHello)
# Handshake completion, both for server and client:
def continueHandshake(self, datagram):

    if dtls.doHandshake(udpSocket, datagram):
        # Check handshake status:
        if dtls.handshakeStatus() == QDlts.HandshakeComplete:
            # Secure DTLS connection is now established.

    else:
        # Error handling.

对于服务器来说,第一次调用doHandshake()需要一个包含ClientHello消息的非空数据报。如果服务器还部署了QDtlsClientVerifier,则第一个ClientHello消息应该是通过QDtlsClientVerifier验证的消息。

如果在握手过程中无法验证对等方的身份,应用程序必须检查由peerVerificationErrors()返回的错误,然后通过调用ignoreVerificationErrors()忽略错误或通过调用abortHandshake()中止握手。如果错误被忽略,可以通过调用resumeHandshake()恢复握手。

握手完成后,可以安全地向网络对等方发送和接收数据报:

# Sending an encrypted datagram:
dtlsConnection.writeDatagramEncrypted(clientSocket, "Hello DTLS server!")
# Decryption:
encryptedMessage = QByteArray(dgramSize)
socket.readDatagram(encryptedMessage.data(), dgramSize)
plainText = dtlsConnection.decryptDatagram(socket, encryptedMessage)

可以使用 shutdown() 关闭 DTLS 连接。

DtlsClient.~DtlsClient()

    clientDtls.shutdown(clientSocket)

警告

建议在销毁客户端的QDtls对象之前调用shutdown(),如果您计划稍后重新使用相同的端口号连接到服务器。否则,服务器可能会丢弃传入的ClientHello消息,更多详情和实现提示请参见RFC 6347,第4.2.8节。

如果服务器不使用QDtlsClientVerifier,它必须配置其QDtls对象以禁用cookie验证过程:

config = QSslConfiguration.defaultDtlsConfiguration()
config.setDtlsCookieVerificationEnabled(False)
# Some other customization ...
dtlsConnection.setDtlsConfiguration(config)

使用非默认生成器参数进行cookie验证的服务器必须在开始握手之前为其QDtls对象设置相同的参数。

注意

DTLS协议将路径最大传输单元(PMTU)发现留给应用程序处理。应用程序可以使用setMtuHint()QDtls提供MTU。这个提示仅影响握手阶段,因为只有握手消息可以被DTLS分片和重新组装。应用程序发送的所有其他消息必须适合单个数据报。

注意

DTLS特定的头部信息增加了应用数据的开销,进一步减少了可能的消息大小。

警告

配置为回复HelloVerifyRequest的服务器将丢弃所有分段的ClientHello消息,永远不会开始握手。

DTLS服务器DTLS客户端示例展示了如何在应用程序中使用QDtls

class HandshakeState

描述DTLS握手的当前状态。

此枚举描述了QDtls连接的当前DTLS握手状态。

常量

描述

QDtls.HandshakeNotStarted

尚未进行任何操作。

QDtls.HandshakeInProgress

握手已启动,目前未发现错误。

QDtls.PeerVerificationFailed

无法建立对等方的身份。

QDtls.HandshakeComplete

握手成功完成并建立了加密连接。

__init__(mode[, parent=None])
Parameters:

创建一个QDtls对象,parent被传递给QObject构造函数。modeSslServerMode用于服务器端DTLS连接,或SslClientMode用于客户端。

另请参阅

sslMode() SslMode

abortHandshake(socket)
Parameters:

socketQUdpSocket

Return type:

布尔

中止正在进行的手势。如果在socket上有一个正在进行的手势,则返回true;否则,设置一个合适的错误并返回false。

cookieGeneratorParameters()
Return type:

GeneratorParameters

返回当前的哈希算法和密钥,无论是默认的还是之前通过调用setCookieGeneratorParameters()设置的。

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

decryptDatagram(socket, dgram)
Parameters:
Return type:

QByteArray

解密 dgram 并将其内容作为纯文本返回。在解密数据报之前必须完成握手。根据 TLS 消息的类型,连接可能会写入 socket,该指针必须有效。

doHandshake(socket[, dgram={}])
Parameters:
Return type:

布尔

警告

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

开始或继续DTLS握手。socket必须是一个有效的指针。当启动服务器端DTLS握手时,dgram必须包含从QUdpSocket读取的初始ClientHello消息。如果未发现错误,此函数返回true。可以使用handshakeState()测试握手状态。false返回意味着发生了某些错误,使用dtlsError()获取更详细的信息。

注意

如果无法建立对等方的身份,错误将设置为PeerVerificationError。如果你想忽略验证错误并继续连接,你必须调用ignoreVerificationErrors(),然后调用resumeHandshake()。如果错误无法忽略,你必须调用abortHandshake()

if not dtls.doHandshake(socket, dgram):
    if dtls.dtlsError() == QDtlsError.PeerVerificationError:
        dtls.abortAfterError(socket)
dtlsConfiguration()
Return type:

QSslConfiguration

返回默认的DTLS配置或之前调用setDtlsConfiguration()设置的配置。

dtlsError()
Return type:

QDtlsError

返回连接遇到的最后一个错误或NoError

另请参阅

dtlsErrorString() QDtlsError

dtlsErrorString()
Return type:

字符串

返回连接遇到的最后一个错误的文本描述或空字符串。

另请参阅

dtlsError()

handleTimeout(socket)
Parameters:

socketQUdpSocket

Return type:

布尔

如果在握手过程中发生超时,将发出handshakeTimeout()信号。应用程序必须调用handleTimeout()来重新传输握手消息;如果发生超时,handleTimeout()返回true,否则返回false。socket必须是一个有效的指针。

另请参阅

handshakeTimeout()

handshakeState()
Return type:

HandshakeState

返回此QDtls的当前握手状态。

handshakeTimeout()

警告

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

数据包丢失可能导致握手阶段出现超时。在这种情况下,QDtls会发出handshakeTimeout()信号。调用handleTimeout()以重新传输握手消息:

def __init__(self):

    # Some initialization code here ...
    clientDtls.handshakeTimeout.connect(self.handleTimeout)

def handleTimeout(self):

    clientDtls.handleTimeout(clientSocket)

另请参阅

handleTimeout()

ignoreVerificationErrors(errorsToIgnore)
Parameters:

errorsToIgnore – QSslError 的列表

警告

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

此方法告诉QDtls仅忽略errorsToIgnore中给出的错误。

例如,如果你想连接到一个使用自签名证书的服务器,请考虑以下代码片段:

cert = QSslCertificate.fromPath("server-certificate.pem")
error = QSslError(QSslError.SelfSignedCertificate, cert.at(0))
expectedSslErrors = QList()
expectedSslErrors.append(error)
dtls = QDtls()
dtls.ignoreVerificationErrors(expectedSslErrors)
dtls.doHandshake(udpSocket)

你也可以在doHandshake()遇到PeerVerificationError错误后调用此函数,然后通过调用resumeHandshake()来恢复握手。

后续对此函数的调用将替换之前调用中传递的错误列表。您可以通过调用此函数并传入一个空列表来清除您想要忽略的错误列表。

isConnectionEncrypted()
Return type:

布尔

如果DTLS握手成功完成,返回true

mtuHint()
Return type:

整数

返回之前由setMtuHint()设置的值。默认值为0。

另请参阅

setMtuHint()

peerAddress()
Return type:

QHostAddress

返回由setPeer()设置的对方地址,或Null

另请参阅

setPeer()

peerPort()
Return type:

整数

返回由setPeer()设置的对等端口号,或0。

另请参阅

setPeer()

peerVerificationErrors()
Return type:

QSslError的列表

返回在建立对等方身份时发现的错误。

如果你想在发生错误的情况下继续连接,你必须调用ignoreVerificationErrors()

peerVerificationName()
Return type:

字符串

返回由setPeer()setPeerVerificationName()设置的主机名。默认值为空字符串。

pskRequired(authenticator)
Parameters:

认证器QSslPreSharedKeyAuthenticator

QDtls 在协商PSK加密套件时发出此信号,因此随后需要PSK认证。

使用PSK时,客户端必须向服务器发送有效的身份和有效的预共享密钥,以便TLS握手继续进行。应用程序可以通过根据其需求填充传递的authenticator对象,在连接到该信号的槽中提供此信息。

注意

忽略此信号,或未能提供所需的凭据,将导致握手失败,从而导致连接中止。

注意

authenticator 对象由 QDtls 拥有,应用程序不得删除它。

resumeHandshake(socket)
Parameters:

socketQUdpSocket

Return type:

布尔

如果在握手期间忽略了peer验证错误,resumeHandshake() 会恢复并完成握手并返回 truesocket 必须是一个有效的指针。如果握手无法恢复,则返回 false

sessionCipher()
Return type:

QSslCipher

返回此连接使用的加密cipher,如果连接未加密,则返回空密码。会话的密码在握手阶段选择。密码用于加密和解密数据。

QSslConfiguration 提供了用于设置密码套件有序列表的函数,握手阶段最终将从中选择会话密码。此有序列表必须在握手阶段开始之前就位。

sessionProtocol()
Return type:

SslProtocol

返回此连接使用的DTLS协议版本,如果连接尚未加密,则返回UnknownProtocol。连接的协议在握手阶段选择。

setDtlsConfiguration() 可以在握手开始前设置首选版本。

setCookieGeneratorParameters(params)
Parameters:

paramsGeneratorParameters

Return type:

布尔

设置加密哈希算法和来自params的密钥。此函数仅用于服务器端的QDtls连接。如果成功,返回true

注意

此函数必须在握手开始之前调用。

setDtlsConfiguration(configuration)
Parameters:

配置QSslConfiguration

Return type:

布尔

configuration设置连接的TLS配置,并在成功时返回true

注意

此函数必须在握手开始之前调用。

setMtuHint(mtuHint)
Parameters:

mtuHint – int

mtuHint 是最大传输单元(MTU),由应用程序发现或猜测。应用程序不需要设置此值。

setPeer(address, port[, verificationName={}])
Parameters:
  • 地址QHostAddress

  • port – int

  • verificationName – str

Return type:

布尔

设置对等方的地址、port和主机名,并在成功时返回trueaddress不能为空、多播或广播。verificationName是用于证书验证的主机名。

setPeerVerificationName(name)
Parameters:

name – str

Return type:

布尔

设置将用于证书验证的主机name,并在成功时返回true

注意

此函数必须在握手开始之前调用。

shutdown(socket)
Parameters:

socketQUdpSocket

Return type:

布尔

发送加密的关闭警报消息并关闭DTLS连接。握手状态变为HandshakeNotStartedsocket必须是一个有效的指针。此函数在成功时返回true

另请参阅

doHandshake()

sslMode()
Return type:

SslMode

返回服务器端连接的SslServerMode和客户端的SslClientMode

另请参阅

QDtls() SslMode

writeDatagramEncrypted(socket, dgram)
Parameters:
Return type:

整数

加密 dgram 并将加密数据写入 socket。返回写入的字节数,如果出错则返回 -1。在写入加密数据之前必须完成握手。socket 必须是一个有效的指针。