QDtls Class
このクラスは、UDPソケットの暗号化機能を提供します。詳細...
| ヘッダー: | #include <QDtls> |
| CMake: | find_package(Qt6 REQUIRED COMPONENTS Network) target_link_libraries(mytarget PRIVATE Qt6::Network) |
| qmake: | QT += network |
| 継承元: | QObject |
- 継承されたメンバーを含む、すべてのメンバーの一覧
- QDtlsは、ネットワークプログラミングAPIの一部です。
パブリック型
| GeneratorParameters | |
| enum | HandshakeState { HandshakeNotStarted, HandshakeInProgress, PeerVerificationFailed, HandshakeComplete } |
パブリック関数
| 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 ¶ms) |
| 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) |
シグナル
| void | handshakeTimeout() |
| void | pskRequired(QSslPreSharedKeyAuthenticator *authenticator) |
関連する非メンバー
| enum class | QDtlsError { NoError, InvalidInputParameters, InvalidOperation, UnderlyingSocketError, RemoteClosedConnectionError, …, TlsNonFatalError } |
詳細な説明
QDtls クラスは、ユーザーデータグラムプロトコル(UDP)を使用して、ネットワークの相手先との間でセキュアな接続を確立するために使用できます。本質的にコネクションレスな UDP 上で DTLS 接続を確立するには、まず両端点が `doHandshake()` を呼び出して、TLS ハンドシェイクを正常に完了させる必要があります。 ハンドシェイクが完了した後、writeDatagramEncrypted() を使用して、暗号化されたデータグラムを相手先に送信できます。相手先から送信されてきた暗号化されたデータグラムは、decryptDatagram() によって復号化できます。
QDtlsは、QUdpSocket との連携を前提に設計されています。QUdpSocket は異なるピアからのデータグラムを受信する可能性があるため、アプリケーションはデマルチプレクシングを実装し、異なるピアからのデータグラムを対応するQDtlsインスタンスに転送する必要があります。 ネットワークピアとその QDtls オブジェクト間の関連付けは、ピアのアドレスとポート番号を使用して確立できます。ハンドシェイクを開始する前に、アプリケーションはsetPeer() を使用してピアのアドレスとポート番号を設定する必要があります。
QDtlsはQUdpSocket からデータグラムを読み取りません。これは、例えばQUdpSocket::readyRead()シグナルにアタッチされたスロット内で、アプリケーションによって行われることが想定されています。その後、これらのデータグラムはQDtlsによって処理されなければなりません。
注:QDtlsは QUdpSocket オブジェクトの所有権を取得しません。
通常、ハンドシェイクフェーズ中は、両方のピア間で複数のデータグラムが送受信されます。データグラムを読み取った際、サーバーとクライアントは、何らかのエラーが検出されるか、handshakeState()がHandshakeComplete を返すまで、これらのデータグラムをdoHandshake()に渡さなければなりません:
// 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.
}
}サーバーの場合、doHandshake() への最初の呼び出しには、ClientHello メッセージを含む空ではないデータグラムが必要です。サーバーがQDtlsClientVerifier も実装している場合、最初の ClientHello メッセージはQDtlsClientVerifier によって検証されたものであることが期待されます。
ハンドシェイク中に相手側の身元を検証できない場合、アプリケーションはpeerVerificationErrors()が返すエラーを検査し、ignoreVerificationErrors()を呼び出してエラーを無視するか、abortHandshake()を呼び出してハンドシェイクを中止する必要があります。エラーが無視された場合、resumeHandshake()を呼び出すことでハンドシェイクを再開できます。
ハンドシェイクが完了すると、ネットワークの相手先との間でデータグラムを安全に送受信できるようになります:
// 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);DTLS接続は、shutdown() を使用して閉じることができます。
DtlsClient::~DtlsClient()
{
clientDtls.shutdown(&clientSocket);
}警告: 後で同じポート番号を使用してサーバーに再接続する予定がある場合は、クライアントの QDtls オブジェクトを破棄する前にshutdown() を呼び出すことを推奨します 。そうしないと、サーバーが着信する ClientHello メッセージを破棄する可能性があります。詳細および実装上のヒントについては、RFC 6347 のセクション 4.2.8 を参照してください。
サーバーが `QDtlsClientVerifier` を使用しない場合は、クッキー検証手順を無効にするよう QDtls オブジェクトを設定する必要があります:
auto config = QSslConfiguration::defaultDtlsConfiguration();
config.setDtlsCookieVerificationEnabled(false);
// Some other customization ...
dtlsConnection.setDtlsConfiguration(config);デフォルト以外のジェネレータパラメータを使用してクッキー検証を行うサーバーは、ハンドシェイクを開始する前に、自身の QDtls オブジェクトに対して同じパラメータを設定する必要があります。
注: DTLS プロトコルでは 、パス最大伝送単位 (PMTU) の検出はアプリケーションに委ねられています。 アプリケーションは、setMtuHint() を使用して QDtls に MTU を指定できます。このヒントはハンドシェイクフェーズにのみ影響します。これは、DTLS によってフラグメント化および再構築されるのはハンドシェイクメッセージのみであるためです。アプリケーションによって送信されるその他のすべてのメッセージは、単一のデータグラムに収まる必要があります。
注:DTLS固有の ヘッダーはアプリケーションデータに一定のオーバーヘッドを追加するため、許容されるメッセージサイズはさらに小さくなります。
警告: HelloVerifyRequestで応答するように設定されたサーバーは 、断片化されたClientHelloメッセージをすべて破棄し、ハンドシェイクを開始することはありません。
DTLS サーバーおよびDTLS クライアントの例は、アプリケーションで QDtls を使用する方法を示しています。
QUdpSocket 、QDtlsClientVerifier 、HandshakeState 、QDtlsError 、およびQSslConfigurationも参照してください 。
メンバ型のドキュメント
[alias] QDtls::GeneratorParameters
enum QDtls::HandshakeState
DTLSハンドシェイクの現在の状態を表します。
この列挙型は、QDtls 接続におけるDTLSハンドシェイクの現在の状態を表します。
| 定数 | 値 | 説明 |
|---|---|---|
QDtls::HandshakeNotStarted | 0 | まだ何も行われていません。 |
QDtls::HandshakeInProgress | 1 | ハンドシェイクが開始され、現時点でエラーは検出されていません。 |
QDtls::PeerVerificationFailed | 2 | ピアの身元を確認できません。 |
QDtls::HandshakeComplete | 3 | ハンドシェイクは正常に完了し、暗号化された接続が確立されました。 |
関連項目: QDtls::doHandshake() およびQDtls::handshakeState()。
メンバ関数のドキュメント
[explicit] QDtls::QDtls(QSslSocket::SslMode mode, QObject *parent = nullptr)
QDtls オブジェクトを作成します。parent がQObject コンストラクタに渡されます。mode は、サーバー側のDTLS接続の場合はQSslSocket::SslServerMode 、クライアントの場合はQSslSocket::SslClientMode となります。
sslMode() およびQSslSocket::SslModeも参照してください 。
[virtual noexcept] QDtls::~QDtls()
QDtls オブジェクトを破棄します。
bool QDtls::abortHandshake(QUdpSocket *socket)
進行中のハンドシェイクを中止します。socket でハンドシェイクが進行中であれば true を返します。そうでない場合は、適切なエラーを設定して false を返します。
doHandshake() およびresumeHandshake()も参照してください 。
QDtls::GeneratorParameters QDtls::cookieGeneratorParameters() const
現在のハッシュアルゴリズムとシークレットを返します。これらはデフォルトのもの、あるいは以前に `setCookieGeneratorParameters()` の呼び出しによって設定されたものです。
デフォルトのハッシュアルゴリズムは、Qtがそれをサポートするように構成されている場合はQCryptographicHash::Sha256 、そうでない場合はQCryptographicHash::Sha1 となります。デフォルトのシークレットは、バックエンド固有の暗号学的に強固な擬似乱数生成器から取得されます。
QDtlsClientVerifier およびsetCookieGeneratorParameters()も参照してください 。
QByteArray QDtls::decryptDatagram(QUdpSocket *socket, const QByteArray &dgram)
dgram を復号化し、その内容を平文として返します。データグラムの復号化を行うには、ハンドシェイクが完了している必要があります。TLSメッセージの種類によっては、接続がsocket に書き込みを行う場合があります。 は有効なポインタである必要があります。
bool QDtls::doHandshake(QUdpSocket *socket, const QByteArray &dgram = {})
DTLSハンドシェイクを開始または継続します。socket は有効なポインタでなければなりません。サーバー側のDTLSハンドシェイクを開始する場合、dgram には、QUdpSocket から読み込まれた初期のClientHelloメッセージが含まれている必要があります。この関数は、エラーが検出されなかった場合、true を返します。ハンドシェイクの状態は、handshakeState()を使用して確認できます。false が返された場合は何らかのエラーが発生したことを意味します。詳細な情報を得るには、dtlsError()を使用してください。
注: 相手側の身元を確認できない場合 、エラーはQDtlsError::PeerVerificationError に設定されます。検証エラーを無視して接続を続行したい場合は、ignoreVerificationErrors()を呼び出した後、resumeHandshake()を呼び出す必要があります。エラーを無視できない場合は、abortHandshake()を呼び出す必要があります。
if (!dtls.doHandshake(&socket, dgram)) {
if (dtls.dtlsError() == QDtlsError::PeerVerificationError)
dtls.abortAfterError(&socket);
}関連項目: handshakeState()、dtlsError()、ignoreVerificationErrors()、resumeHandshake()、およびabortHandshake()。
QSslConfiguration QDtls::dtlsConfiguration() const
デフォルトの DTLS 設定、または以前に `setDtlsConfiguration()` を呼び出して設定された設定のいずれかを返します。
setDtlsConfiguration() およびQSslConfiguration::defaultDtlsConfiguration()も参照してください 。
QDtlsError QDtls::dtlsError() const
接続で最後に発生したエラー、または `QDtlsError::NoError` を返します。
dtlsErrorString() およびQDtlsErrorも参照してください 。
QString QDtls::dtlsErrorString() const
接続で最後に発生したエラーに関する説明テキスト、または空の文字列を返します。
dtlsError()も参照してください 。
bool QDtls::handleTimeout(QUdpSocket *socket)
ハンドシェイク中にタイムアウトが発生した場合、handshakeTimeout() シグナルが発信されます。アプリケーションは、ハンドシェイクメッセージを再送信するために handleTimeout() を呼び出す必要があります。handleTimeout() は、タイムアウトが発生した場合はtrue を返し、それ以外の場合は false を返します。socket は有効なポインタでなければなりません。
handshakeTimeout()も参照してください 。
QDtls::HandshakeState QDtls::handshakeState() const
このQDtls の現在のハンドシェイク状態を返します。
doHandshake() およびQDtls::HandshakeStateも参照してください 。
[signal] void QDtls::handshakeTimeout()
パケット損失が発生すると、ハンドシェイクフェーズ中にタイムアウトが生じる可能性があります。この場合、QDtls はhandshakeTimeout()シグナルを発行します。handleTimeout()を呼び出して、ハンドシェイクメッセージを再送信してください:
DtlsClient::DtlsClient()
{
// Some initialization code here ...
connect(&clientDtls, &QDtls::handshakeTimeout, this, &DtlsClient::handleTimeout);
}
void DtlsClient::handleTimeout()
{
clientDtls.handleTimeout(&clientSocket);
}handleTimeout()も参照してください 。
void QDtls::ignoreVerificationErrors(const QList<QSslError> &errorsToIgnore)
この方法では、QDtls に対し、errorsToIgnore に指定されたエラーのみを無視するように指示します。
たとえば、自己署名証明書を使用するサーバーに接続したい場合は、次のコードスニペットを参照してください。
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);また、doHandshake() がQDtlsError::PeerVerificationError のエラーを検出した後にこの関数を呼び出し、その後resumeHandshake() を呼び出すことでハンドシェイクを再開することもできます。
この関数をその後呼び出すと、以前の呼び出しで渡されたエラーのリストが上書きされます。無視したいエラーのリストをクリアするには、空のリストを引数としてこの関数を呼び出します。
doHandshake()、resumeHandshake()、およびQSslErrorも参照してください 。
bool QDtls::isConnectionEncrypted() const
DTLSハンドシェイクが正常に完了した場合、true を返します。
doHandshake() およびhandshakeState()も参照してください 。
quint16 QDtls::mtuHint() const
setMtuHint() で以前に設定された値を返します。デフォルト値は 0 です。
setMtuHint()も参照してください 。
QHostAddress QDtls::peerAddress() const
setPeer() またはQHostAddress::Null によって設定されたピアのアドレスを返します。
setPeer()も参照してください 。
quint16 QDtls::peerPort() const
setPeer() で設定されたピアのポート番号、または 0 を返します。
setPeer()も参照してください 。
QList<QSslError> QDtls::peerVerificationErrors() const
ピアの識別情報を確立する際に検出されたエラーを返します。
発生したエラーにもかかわらず接続を続行したい場合は、ignoreVerificationErrors() を呼び出す必要があります。
QString QDtls::peerVerificationName() const
setPeer() またはsetPeerVerificationName() で設定されたホスト名を返します。デフォルト値は空の文字列です。
setPeerVerificationName() およびsetPeer()も参照してください 。
[signal] void QDtls::pskRequired(QSslPreSharedKeyAuthenticator *authenticator)
QDtls PSK暗号スイートをネゴシエートする際にこの信号を出力するため、その後PSK認証が必要となります。
PSK を使用する場合、TLS ハンドシェイクを継続するためには、クライアントはサーバーに対して有効な識別情報と有効な事前共有鍵を送信する必要があります。アプリケーションは、このシグナルに接続されたスロット内で、渡された `authenticator ` オブジェクトを必要に応じて設定することで、この情報を提供できます。
注: このシグナルを無視したり 、必要な認証情報を提供しなかったりすると、ハンドシェイクが失敗し、その結果、接続が中断されます。
注: authenticator オブジェクトは QDtls が所有しており、アプリケーションがこれを削除してはなりません。
「QSslPreSharedKeyAuthenticator」も参照してください 。
bool QDtls::resumeHandshake(QUdpSocket *socket)
ハンドシェイク中にピア検証エラーが無視された場合、resumeHandshake() はハンドシェイクを再開・完了させ、true を返します。socket は有効なポインタでなければなりません。ハンドシェイクを再開できなかった場合は、false を返します。
doHandshake()、abortHandshake()、peerVerificationErrors()、およびignoreVerificationErrors()も参照してください 。
QSslCipher QDtls::sessionCipher() const
この接続で使用される暗号化cipher を返します。接続が暗号化されていない場合は、null cipherを返します。セッションの暗号は、ハンドシェイクフェーズ中に選択されます。この暗号は、データの暗号化および復号化に使用されます。
QSslConfiguration ハンドシェイクフェーズにおいて最終的にセッション暗号が選択される、暗号の順序付きリストを設定するための関数を提供します。この順序付きリストは、ハンドシェイクフェーズが開始される前に用意されていなければなりません。
QSslConfiguration 、setDtlsConfiguration()、およびdtlsConfiguration()も参照してください 。
QSsl::SslProtocol QDtls::sessionProtocol() const
この接続で使用されている DTLS プロトコルのバージョンを返します。接続がまだ暗号化されていない場合は、UnknownProtocol を返します。接続に使用するプロトコルは、ハンドシェイクフェーズ中に選択されます。
setDtlsConfiguration() を使用すると、ハンドシェイクが開始される前に優先バージョンを設定できます。
関連項目: setDtlsConfiguration()、QSslConfiguration 、QSslConfiguration::defaultDtlsConfiguration()、およびQSslConfiguration::setProtocol()。
bool QDtls::setCookieGeneratorParameters(const QDtls::GeneratorParameters ¶ms)
params から暗号ハッシュアルゴリズムとシークレットを設定します。この関数は、サーバーサイドのQDtls 接続でのみ必要です。成功した場合はtrue を返します。
注:この関数は 、ハンドシェイクが開始される前に呼び出す必要があります。
関連項目: cookieGeneratorParameters()、doHandshake()、QDtlsClientVerifier 、およびQDtlsClientVerifier::cookieGeneratorParameters()。
bool QDtls::setDtlsConfiguration(const QSslConfiguration &configuration)
configuration から接続の TLS 設定を設定し、成功した場合はtrue を返します。
注:この関数は 、ハンドシェイクが開始される前に呼び出す必要があります。
関連項目: dtlsConfiguration() およびdoHandshake()。
void QDtls::setMtuHint(quint16 mtuHint)
mtuHint これは、アプリケーションによって検出されたか、あるいは推測された最大伝送単位(MTU)です。アプリケーションがこの値を設定する必要はありません。
mtuHint() およびQAbstractSocket::PathMtuSocketOptionも参照してください 。
bool QDtls::setPeer(const QHostAddress &address, quint16 port, const QString &verificationName = {})
ピアのアドレス(port )およびホスト名を設定し、成功した場合はtrue を返します。address は、null、マルチキャスト、またはブロードキャストであってはなりません。verificationName は、証明書の検証に使用されるホスト名です。
peerAddress()、peerPort()、およびpeerVerificationName()も参照してください 。
bool QDtls::setPeerVerificationName(const QString &name)
証明書の検証に使用するホストname を設定し、成功した場合はtrue を返します。
注:この関数は 、ハンドシェイクが開始される前に呼び出す必要があります。
関連項目: peerVerificationName() およびsetPeer()。
bool QDtls::shutdown(QUdpSocket *socket)
暗号化されたシャットダウン通知メッセージを送信し、DTLS接続を閉じます。ハンドシェイクの状態はQDtls::HandshakeNotStarted に変更されます。socket は有効なポインタでなければなりません。この関数は、成功した場合にtrue を返します。
doHandshake()も参照してください 。
QSslSocket::SslMode QDtls::sslMode() const
サーバー側の接続の場合は `QSslSocket::SslServerMode ` を、クライアント側の場合は `QSslSocket::SslClientMode ` を返します。
QDtls() およびQSslSocket::SslModeも参照してください 。
qint64 QDtls::writeDatagramEncrypted(QUdpSocket *socket, const QByteArray &dgram)
dgram を暗号化し、暗号化されたデータをsocket に書き込みます。書き込まれたバイト数を返します。エラーが発生した場合は -1 を返します。暗号化されたデータを書き込む前に、ハンドシェイクを完了させる必要があります。socket は有効なポインタでなければなりません。
doHandshake()、handshakeState()、isConnectionEncrypted()、およびdtlsError()も参照してください 。
関連する非メンバー関数
enum class QDtlsError
QDtls およびQDtlsClientVerifier によって検出される可能性のあるエラーについて説明します。
この列挙型は、QDtlsClientVerifier およびQDtls の各クラスのオブジェクトで発生し得る、一般的なエラーおよび TLS 固有のエラーを記述しています。
| 定数 | 値 | 説明 |
|---|---|---|
QDtls::QDtlsError::NoError | 0 | エラーは発生せず、最後の操作は成功しました。 |
QDtls::QDtlsError::InvalidInputParameters | 1 | 呼び出し元から提供された入力パラメータが無効でした。 |
QDtls::QDtlsError::InvalidOperation | 2 | 操作が許可されていない状態で操作が試行されました。 |
QDtls::QDtlsError::UnderlyingSocketError | 3 | QUdpSocket::writeDatagram() が失敗しました。QUdpSocket::error() およびQUdpSocket::errorString() により、より具体的な情報を得ることができます。 |
QDtls::QDtlsError::RemoteClosedConnectionError | 4 | TLS シャットダウン警告メッセージを受信しました。 |
QDtls::QDtlsError::PeerVerificationError | 5 | TLS ハンドシェイク中に、ピアの身元を確認できませんでした。 |
QDtls::QDtlsError::TlsInitializationError | 6 | 基盤となる TLS バックエンドの初期化中にエラーが発生しました。 |
QDtls::QDtlsError::TlsFatalError | 7 | TLS ハンドシェイク中に、ピアの検証エラーや TLS 初期化エラー以外の致命的なエラーが発生しました。 |
QDtls::QDtlsError::TlsNonFatalError | 8 | データグラムの暗号化または復号化に失敗しました。これは致命的なエラーではなく、QDtls はこのエラー後も動作を継続できます。 |
© 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.