- class QDtls#
此类为UDP套接字提供加密。 更多…
概述#
方法#
def
__init__()
定义
dtlsError()
定义
mtuHint()
定义
peerPort()
定义
setMtuHint()
定义
setPeer()
定义
shutdown()
定义
sslMode()
信号#
注意
本文档可能包含从 C++ 自动翻译到 Python 的片段。我们始终欢迎对片段翻译的贡献。如果您发现翻译有问题,您也可以通过在 https:/bugreports.qt.io/projects/PYSIDE 上创建工单来通知我们。
详细描述#
警告
本节包含从 C++ 自动翻译到 Python 的片段,可能包含错误。
QDtls
类可用于使用用户数据报协议 (UDP) 与网络对等体建立安全连接。无连接的 UDP 上的 DTLS 连接意味着两个对等体首先必须成功完成 TLS 握手,通过调用doHandshake()
。握手完成后,可以使用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()
的首次调用需要一个包含客户端问候信息的非空数据报。如果服务器也部署了QDtlsClientVerifier
,则期望第一个客户端问候信息是由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()
将 MTU 提供给QDtls
。此提示仅影响握手阶段,因为只有握手消息可以被DTLS分片和重新组装。所有其他由应用程序发送的消息都必须适合单个数据包。注意
DTLS特定的头部为应用程序数据添加了一些开销,进一步减少了可能的消息大小。
警告
配置为回复 HelloVerifyRequest 的服务器将丢弃所有分片的 ClientHello 消息,永远不会启动握手。
DTLS服务器 和 DTLS客户端 示例说明了如何在应用程序中使用
QDtls
。另请参阅
QUdpSocket
QDtlsClientVerifier
HandshakeState
QDtlsError
QSslConfiguration
- class HandshakeState#
描述了DTLS握手的当前状态。
此枚举描述了
QDtls
连接的当前握手状态。常量
描述
QDtls.HandshakeNotStarted
还没有做任何事情。
QDtls.HandshakeInProgress
已经启动了握手,且迄今为止没有错误。
QDtls.PeerVerificationFailed
无法建立对等方的身份。
QDtls.HandshakeComplete
握手成功完成,并建立了加密连接。
创建一个
QDtls
对象,将parent
传递给QObject
构造函数。《mode》对于服务器端的 DTLS 连接是SslServerMode
,对于客户端是SslClientMode
。- abortHandshake(socket)#
- 参数:
socket -
QUdpSocket
- 返回类型:
布尔值
取消正在进行的手动握手。如果
socket
中有一个正在进行的手动过程,则返回 true;否则,设置适当的错误并返回 false。- decryptDatagram(socket, dgram)#
- 参数:
socket -
QUdpSocket
dgram -
QByteArray
- 返回类型:
解密
dgram
并将其内容作为纯文本返回。在解密数据报文之前必须完成手动过程。根据 TLS 消息的类型,连接可能会写入socket
,该socket
必须是有效的指针。- doHandshake(socket[, dgram={}])#
- 参数:
socket -
QUdpSocket
dgram -
QByteArray
- 返回类型:
布尔值
警告
本节包含从 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()#
- 返回类型:
返回默认 DTLS 配置或通过先前调用
setDtlsConfiguration()
设置的配置。- dtlsError()#
- 返回类型:
QDtlsError
返回连接遇到的上一个错误或
NoError
。另请参阅
dtlsErrorString()
QDtlsError
- dtlsErrorString()#
- 返回类型:
str
返回连接遇到的上一个错误的文本描述或空字符串。
另请参阅
- handleTimeout(socket)#
- 参数:
socket -
QUdpSocket
- 返回类型:
布尔值
如果在握手期间发生超时,将发出
handshakeTimeout()
信号。应用程序必须调用 handleTimeout() 以重新发送握手消息;当发生超时时,handleTimeout() 返回true
,否则返回 false。socket
必须是一个有效的指针。另请参阅
- 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)
另请参阅
- ignoreVerificationErrors(errorsToIgnore)#
- 参数:
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()#
- 返回类型:
布尔值
如果 DTLS 握手成功完成,则返回
true
。- mtuHint()#
- 返回类型:
整型
返回由
setMtuHint()
设置的值。默认值为 0。另请参阅
- peerAddress()#
- 返回类型:
返回对等方的地址,由
setPeer()
设置,或Null
。另请参阅
- peerPort()#
- 返回类型:
整型
返回对等方的端口编号,由
setPeer()
设置,或 0。另请参阅
- peerVerificationErrors()#
- 返回类型:
QSslError 列表
在建立对等方身份时找到的错误。
如果您想要继续连接,尽管已发生错误,您必须调用
ignoreVerificationErrors()
。- peerVerificationName()#
- 返回类型:
str
返回由
setPeer()
或setPeerVerificationName()
设置的域名。默认值为空字符串。- pskRequired(authenticator)#
- 参数:
QDtls
在协商 PSK 密码组时会发出此信号,因此需要进行 PSK 验证。使用 PSK 时,客户端必须向服务器发送一个有效的身份和一个有效的预共享密钥,以便 TLS 握手可以继续进行。应用程序可以通过连接到该信号的槽来提供这些信息,根据需求填充传递的
authenticator
对象。注意
忽略此信号或无法提供所需的凭据,会导致握手失败,从而中断连接。
- resumeHandshake(socket)#
- 参数:
socket -
QUdpSocket
- 返回类型:
布尔值
如果在握手过程中忽略了 Peer 验证错误,则 resumeHandshake() 会恢复并完成握手并返回
true
。socket
必须是一个有效的指针。如果不能恢复握手,则返回false
。- sessionCipher()#
- 返回类型:
返回此连接使用的加密算法
cipher
,如果没有加密,则返回空加密算法。会话密码在握手阶段被选中。密码用于加密和解密数据。QSslConfiguration
提供了设置在握手阶段将从中选择会话密码的密码顺序列表的函数。在握手阶段开始之前,必须设置这个顺序列表。- sessionProtocol()#
- 返回类型:
返回此连接使用的DTLS协议版本,如果连接尚未加密,则返回UnknownProtocol。连接的协议在握手阶段选择。
setDtlsConfiguration()
可以在握手开始之前设置首选版本。- setDtlsConfiguration(configuration)#
- 参数:
configuration –
QSslConfiguration
- 返回类型:
布尔值
设置连接的TLS配置为
configuration
,如果成功则返回true
。- setMtuHint(mtuHint)#
- 参数:
mtuHint – int
mtuHint
是最大传输单元(MTU),可以是应用程序发现或猜测的。应用程序无需设置此值。- setPeer(address, port[, verificationName={}])#
- 参数:
address –
QHostAddress
port – int
verificationName – str
- 返回类型:
布尔值
设置对等方的地址、
端口号
和主机名,并在成功时返回true
。地址address
不能为null、多播或广播。verificationName
是用于证书验证的主机名。- setPeerVerificationName(name)#
- 参数:
name – 字符串
- 返回类型:
布尔值
设置用于证书验证的主机
name
并在成功时返回true
。- shutdown(socket)#
- 参数:
socket -
QUdpSocket
- 返回类型:
布尔值
发送加密的关闭警告消息并关闭DTLS连接。握手状态变为
HandshakeNotStarted
。socket
必须是一个有效的指针。此函数成功时返回true
。另请参阅
对于服务器端连接返回
SslServerMode
,对于客户端则返回SslClientMode
。另请参阅
QDtls()
SslMode
- writeDatagramEncrypted(socket, dgram)#
- 参数:
socket -
QUdpSocket
dgram -
QByteArray
- 返回类型:
整型
加密
dgram
并将加密数据写入到socket
。返回写入的字节数,或者在出错时返回-1。在写入加密数据之前必须完成握手。socket
必须是一个有效的指针。