Signatur
Beschreibung
RTCCertificateStats ist ein Wörterbuch (Dictionary) der WebRTC-Statistik-API. Du erzeugst es nicht selbst. Es taucht als Eintrag im RTCStatsReport auf, den RTCPeerConnection.getStats() zurückgibt. Solche Einträge erkennst du an type === "certificate". Jeder Eintrag beschreibt genau ein Zertifikat, das beim DTLS-Handshake eines RTCDtlsTransport (und damit auf dem zugrunde liegenden RTCIceTransport) benutzt wird. Das kann das eigene (lokale) Zertifikat sein oder das der Gegenstelle.
Neben den allgemeinen RTCStats-Feldern id, timestamp und type enthält der Eintrag:
fingerprint: der Fingerabdruck des Zertifikats als Hex-Zeichenkette mit Doppelpunkten, z. B."AB:CD:…".fingerprintAlgorithm: der Hash-Algorithmus des Fingerabdrucks, z. B."sha-256".base64Certificate: das DER-kodierte Zertifikat als Base64-Zeichenkette.issuerCertificateId(optional): dieiddes Stats-Eintrags für das ausstellende Zertifikat. Darüber kannst du einer Zertifikatskette folgen.
Welche Zertifikate zu einer Verbindung gehören, verraten die RTCTransportStats-Einträge (type === "transport") über ihre Felder localCertificateId und remoteCertificateId. Typische Einsatzfälle sind Diagnose-Werkzeuge, Protokollierung und ein Sicherheitsabgleich: Du kannst den tatsächlich verhandelten Fingerabdruck mit dem Wert vergleichen, der über die Signalisierung in der SDP (a=fingerprint) mitgeschickt wurde. Das hilft, Man-in-the-Middle-Angriffe zu erkennen.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $id Pflicht | string | Eindeutige Kennung dieses Stats-Eintrags innerhalb des Reports. Darauf verweisen localCertificateId, remoteCertificateId und issuerCertificateId. |
|
| $timestamp Pflicht | DOMHighResTimeStamp | Zeitpunkt, zu dem die Statistik erfasst wurde. | |
| $type Pflicht | string | "certificate" | Immer "certificate". |
| $fingerprint Pflicht | string | Fingerabdruck des Zertifikats als Hex-Zeichenkette mit Doppelpunkten, wie sie auch in der SDP steht. | |
| $fingerprintAlgorithm Pflicht | string | Hash-Funktion, mit der der Fingerabdruck berechnet wurde, z. B. "sha-256". |
|
| $base64Certificate Pflicht | string | DER-kodiertes Zertifikat, Base64-kodiert, ohne PEM-Kopf- und Fußzeilen. | |
| $issuerCertificateId | string | undefined | id des Stats-Eintrags für das Zertifikat des Ausstellers. Fehlt bei selbstsignierten Zertifikaten, und das ist bei WebRTC der Normalfall. |
Rückgabewert
RTCStatsReport-Eintrags, den getStats() liefert.Beispiele
Alle Zertifikat-Statistiken einer Verbindung ausgeben
// pc ist eine bereits verbundene RTCPeerConnection
const logCertificates = async (pc) => {
const report = await pc.getStats();
report.forEach((stat) => {
if (stat.type === 'certificate') {
console.log(stat.id, stat.fingerprintAlgorithm, stat.fingerprint);
}
});
};
await logCertificates(pc);
Lokales und entferntes Zertifikat über den Transport zuordnen
const getDtlsFingerprints = async (pc) => {
const report = await pc.getStats();
const transport = [...report.values()].find((s) => s.type === 'transport');
if (!transport) return null;
const local = report.get(transport.localCertificateId);
const remote = report.get(transport.remoteCertificateId);
return {
local: local?.fingerprint,
remote: remote?.fingerprint,
algorithm: remote?.fingerprintAlgorithm
};
};
const fp = await getDtlsFingerprints(pc);
// Mit dem Fingerabdruck aus der Remote-SDP vergleichen
const sdpFp = pc.remoteDescription.sdp
.match(/a=fingerprint:\S+ (\S+)/)?.[1];
console.log('Fingerabdruck stimmt überein:', fp?.remote === sdpFp);
Zertifikat als PEM exportieren und Aussteller-Kette verfolgen
const toPem = (b64) =>
`-----BEGIN CERTIFICATE-----\n${b64.match(/.{1,64}/g).join('\n')}\n-----END CERTIFICATE-----`;
const dumpChain = async (pc, certId) => {
const report = await pc.getStats();
let cert = report.get(certId);
while (cert) {
console.log(toPem(cert.base64Certificate));
cert = cert.issuerCertificateId
? report.get(cert.issuerCertificateId)
: undefined;
}
};
const report = await pc.getStats();
const transport = [...report.values()].find((s) => s.type === 'transport');
await dumpChain(pc, transport.remoteCertificateId);
// Wichtig · Fallstricke
- Zeitpunkt: Zertifikat-Einträge stehen erst im Report, wenn der DTLS-Handshake abgeschlossen ist. Das entfernte Zertifikat fehlt davor. Frag die Statistik also erst ab, wenn
connectionState === "connected"ist. - Browser-Unterstützung: Chromium-basierte Browser und Safari liefern
"certificate"-Einträge. Firefox liefert sie bislang nicht. Prüfe deshalb immer, ob die Einträge überhaupt vorhanden sind, und verwende optionale Verkettung (?.). - Format:
base64Certificateenthält reine DER-Daten in Base64. Für PEM musst du Kopf- und Fußzeile selbst ergänzen. Derfingerprintwird in Großbuchstaben mit Doppelpunkten geliefert. Normalisiere die Groß- und Kleinschreibung, bevor du ihn mit SDP-Werten vergleichst. - Sicherheit: WebRTC-Zertifikate sind meist selbstsigniert,
issuerCertificateIdfehlt daher in der Regel. Vertrauen entsteht nur über den Fingerabdruck-Abgleich mit einer sicheren Signalisierung. Ein kompromittierter Signalisierungskanal kann auch den Fingerabdruck in der SDP fälschen. - Die
id-Werte sind browserspezifisch und nicht über mehrere Sitzungen hinweg stabil. Speichere sie nicht dauerhaft.