Signatur
Beschreibung
Die Eigenschaft localCertificateId des Wörterbuchs RTCTransportStats enthält einen String. Er verweist auf einen anderen Eintrag im selben RTCStatsReport, nämlich auf ein Objekt vom Typ "certificate" (RTCCertificateStats). Dieses Objekt beschreibt das lokale Zertifikat, mit dem sich der eigene Peer im DTLS-Handshake des zugehörigen RTCIceTransport ausweist.
Der Wert selbst ist also kein Zertifikat, sondern nur ein Verweis. Um an Fingerabdruck (fingerprint), Hash-Algorithmus (fingerprintAlgorithm) oder das Base64-kodierte DER-Zertifikat (base64Certificate) zu kommen, suchst du mit report.get(transport.localCertificateId) den passenden Eintrag im Bericht.
Typische Anwendungsfälle sind Diagnose und Sicherheitsprüfungen: Du kannst den tatsächlich verwendeten lokalen Fingerabdruck mit dem in der SDP ausgehandelten a=fingerprint vergleichen, Verbindungsprobleme debuggen oder zusammen mit remoteCertificateId nachvollziehen, welche Zertifikate beide Seiten benutzen.
Rückgabewert
RTCCertificateStats-Eintrags im RTCStatsReport. undefined, solange noch kein DTLS-Handshake stattgefunden hat oder der Browser die Eigenschaft nicht unterstützt.Beispiele
Lokale Zertifikat-ID aus den Transport-Statistiken lesen
const logLocalCertificateId = async (pc) => {
const report = await pc.getStats();
report.forEach((stats) => {
if (stats.type === 'transport') {
console.log('Transport:', stats.id);
console.log('Lokale Zertifikat-ID:', stats.localCertificateId ?? '(noch nicht verfügbar)');
}
});
};
// Aufruf, nachdem die Verbindung steht
// pc.addEventListener('connectionstatechange', () => {
// if (pc.connectionState === 'connected') logLocalCertificateId(pc);
// });
Fingerabdruck des lokalen Zertifikats auflösen
const getLocalFingerprint = async (pc) => {
const report = await pc.getStats();
for (const stats of report.values()) {
if (stats.type !== 'transport' || !stats.localCertificateId) continue;
const cert = report.get(stats.localCertificateId);
if (cert) {
return {
algorithm: cert.fingerprintAlgorithm,
fingerprint: cert.fingerprint
};
}
}
return null;
};
const info = await getLocalFingerprint(pc);
console.log(info);
Mit dem SDP-Fingerabdruck abgleichen
const verifyLocalFingerprint = async (pc) => {
const sdp = pc.localDescription?.sdp ?? '';
const match = sdp.match(/a=fingerprint:(\S+) (\S+)/);
if (!match) return false;
const [, sdpAlgo, sdpFingerprint] = match;
const report = await pc.getStats();
const transport = [...report.values()].find((s) => s.type === 'transport');
const cert = transport?.localCertificateId
? report.get(transport.localCertificateId)
: undefined;
const ok = cert?.fingerprintAlgorithm === sdpAlgo &&
cert?.fingerprint.toUpperCase() === sdpFingerprint.toUpperCase();
console.log('Fingerabdruck stimmt überein:', ok);
return ok;
};
// Wichtig · Fallstricke
- Nur ein Verweis: Der Wert ist eine Stats-ID, kein Zertifikat. Das Format der ID legt der Browser fest (z. B.
CF…in Chrome) und kann sich ändern. Parse die ID nie, sondern löse sie immer mitreport.get()auf. - Zeitpunkt: Vor dem DTLS-Handshake (also solange
dtlsStatenicht"connected"ist) fehlt die Eigenschaft meist. Frag die Statistiken deshalb erst ab, wenn die Verbindung steht. - Bundle: Bei
max-bundlegibt es in der Regel nur einen Transport-Eintrag. Ohne Bundle kann es mehrere geben, jeden mit eigenerlocalCertificateId. - Browser-Unterstützung: Chromium-Browser und Safari unterstützen die Eigenschaft. Firefox liefert
RTCTransportStatsnur eingeschränkt, dort kann der Wert fehlen. Prüfe ihn deshalb vor der Nutzung, z. B. mit?.oder??. - Sicherheit: Mit dem Fingerabdruck kannst du die Identität gegen die Signalisierung prüfen. Ein Vergleich mit der eigenen lokalen SDP schützt aber nicht gegen einen Angreifer in der Signalisierung. Dafür musst du den Fingerabdruck über einen unabhängigen, vertrauenswürdigen Kanal abgleichen.