Signatur
Beschreibung
Das Interface RTCDtlsTransport steht für die DTLS-Schicht (Datagram Transport Layer Security) einer WebRTC-Verbindung. Über diesen Transport laufen die verschlüsselten RTP- und RTCP-Pakete der RTCRtpSender- und RTCRtpReceiver-Objekte sowie die SCTP-Pakete von RTCDataChannels. Man erzeugt es nie selbst. Der Browser legt es bei der Aushandlung an, und man erreicht es über sender.transport, receiver.transport oder pc.sctp.transport.
Die wichtigsten Mitglieder sind:
state: der aktuelle DTLS-Zustand, also"new","connecting","connected","closed"oder"failed".iceTransport: das darunterliegendeRTCIceTransport-Objekt mit Informationen über die ICE-Kandidatenpaare.getRemoteCertificates(): gibt ein Array vonArrayBuffers mit den DER-kodierten Zertifikaten der Gegenseite zurück.- Events:
statechange(auch alsonstatechange) underror(auch alsonerror, liefert einRTCErrorEvent).
In der Praxis nutzt man RTCDtlsTransport für die Diagnose. Damit lässt sich genauer als mit connectionState feststellen, ob die Verschlüsselung tatsächlich steht, ob ein DTLS-Handshake fehlgeschlagen ist oder welches Zertifikat die Gegenseite vorgelegt hat. Mit dem Standard-Bündelungsverhalten (bundlePolicy: "max-bundle") teilen sich meist alle Sender, Empfänger und der SCTP-Transport ein einziges RTCDtlsTransport-Objekt.
Rückgabewert
RTCRtpSender.transport, RTCRtpReceiver.transport oder RTCSctpTransport.transport. Vor der Aushandlung ist der Wert null.Beispiele
DTLS-Transport eines Senders ermitteln und Zustand überwachen
const pc = new RTCPeerConnection();
const stream = await navigator.mediaDevices.getUserMedia({ audio: true });
const sender = pc.addTrack(stream.getAudioTracks()[0], stream);
// Die Transport-Objekte gibt es erst nach setLocalDescription
await pc.setLocalDescription(await pc.createOffer());
const dtls = sender.transport;
console.log('DTLS-Zustand:', dtls.state);
dtls.addEventListener('statechange', () => {
console.log('DTLS-Zustand geändert:', dtls.state);
if (dtls.state === 'failed') {
console.error('DTLS-Handshake fehlgeschlagen');
}
});
Fehler über die on-Property abfangen
const handleDtls = (dtls) => {
dtls.onerror = (event) => {
const err = event.error; // RTCError
console.error('DTLS-Fehler:', err.errorDetail, err.message);
};
dtls.onstatechange = () => console.log('Zustand:', dtls.state);
};
// Beispielaufruf, sobald die Verbindung ausgehandelt ist
const [sender] = pc.getSenders();
if (sender?.transport) handleDtls(sender.transport);
Zertifikat der Gegenseite als SHA-256-Fingerprint ausgeben
const fingerprint = async (buffer) => {
const hash = await crypto.subtle.digest('SHA-256', buffer);
return [...new Uint8Array(hash)]
.map((b) => b.toString(16).padStart(2, '0').toUpperCase())
.join(':');
};
const dtls = pc.getReceivers()[0].transport;
if (dtls.state === 'connected') {
const certs = dtls.getRemoteCertificates();
for (const cert of certs) {
console.log('Remote-Fingerprint:', await fingerprint(cert));
}
}
Vom DTLS- zum ICE-Transport navigieren
const dtls = pc.sctp?.transport ?? pc.getSenders()[0]?.transport;
const ice = dtls?.iceTransport;
ice?.addEventListener('selectedcandidatepairchange', () => {
const pair = ice.getSelectedCandidatePair();
console.log('Lokal:', pair.local.type, '→ Remote:', pair.remote.type);
});
// Wichtig · Fallstricke
- Erst nach der Aushandlung verfügbar:
sender.transportundreceiver.transportsindnull, solangesetLocalDescription()odersetRemoteDescription()noch nicht aufgerufen wurde. Vor dem Zugriff also immer aufnullprüfen, z. B. mit optionaler Verkettung (?.). - Geteiltes Objekt: Beim Bundling teilen sich mehrere Sender und Empfänger ein einziges
RTCDtlsTransport-Objekt. Wer an jedem Sender einen Listener anmeldet, registriert ihn womöglich mehrfach am selben Objekt. getRemoteCertificates()liefert erst im Zustand"connected"Daten, vorher ist das Array leer. Die Zertifikate sind DER-kodiert. Zum Vergleich mit dem SDP-Fingerprint muss man selbst hashen, z. B. mitcrypto.subtle.digest.- Ein beendeter Transport bleibt beendet:
"closed"und"failed"sind Endzustände. Um die Verbindung wiederherzustellen, braucht es einen ICE-Neustart (pc.restartIce()) oder eine neueRTCPeerConnection. - Browser-Kompatibilität: Chrome und Edge unterstützen das Interface ab Version 72 bzw. 79, Safari ab 15.4 und Firefox erst ab Version 122. In älteren Firefox-Versionen fehlen
sender.transportundreceiver.transport, dort bleibt als Ausweichlösung nurpc.connectionState. Eine Funktionserkennung ist mit'RTCDtlsTransport' in windowmöglich. - Sicherheit: DTLS-SRTP ist in WebRTC Pflicht, unverschlüsselte Medien sind nicht möglich. Die Echtheit der Gegenseite hängt aber davon ab, dass das SDP mit dem Fingerprint über einen vertrauenswürdigen Signalisierungskanal (HTTPS/WSS) übertragen wird.