Start · Sprachen · JavaScript · Referenz · RTCCertificateStats

RTCCertificateStats

Schnittstelle

Statistik-Wörterbuch vom Typ <code>"certificate"</code>, das Fingerabdruck, Hash-Algorithmus und DER-Daten eines Zertifikats meldet, das ein <code>RTCDtlsTransport</code> verwendet.

seit JavaScript Chromium-Browser und Safari; Firefox liefert bisla Kategorie: webapi

Signatur

interface RTCCertificateStats extends RTCStats

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): die id des 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

Typ
RTCCertificateStats
Beschreibung
Ein einfaches Objekt mit den oben genannten Feldern. Du bekommst es als Wert eines 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);
CFAB:12:... sha-256 AB:12:9F:...:3C CF7E:44:... sha-256 7E:44:01:...:D2

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);
Fingerabdruck stimmt überein: true

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);
-----BEGIN CERTIFICATE----- MIIBFjCBvaADAgECAgkA... -----END CERTIFICATE-----

// 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: base64Certificate enthält reine DER-Daten in Base64. Für PEM musst du Kopf- und Fußzeile selbst ergänzen. Der fingerprint wird in Großbuchstaben mit Doppelpunkten geliefert. Normalisiere die Groß- und Kleinschreibung, bevor du ihn mit SDP-Werten vergleichst.
  • Sicherheit: WebRTC-Zertifikate sind meist selbstsigniert, issuerCertificateId fehlt 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.