Signatur
Beschreibung
Die Methode getFingerprints() der Schnittstelle RTCCertificate liefert die kryptografischen Fingerprints des Zertifikats, das eine RTCPeerConnection für den DTLS-Handshake verwendet. Jeder Eintrag ist ein Objekt vom Typ RTCDtlsFingerprint mit den Eigenschaften algorithm (z. B. "sha-256") und value (Hashwert als hexadezimale Zeichenkette in Kleinbuchstaben, Bytes durch Doppelpunkte getrennt).
Genau diese Werte stehen im SDP als Zeile a=fingerprint:sha-256 AB:CD:…. Über den Signalisierungskanal tauschen beide Seiten sie aus, und beim DTLS-Handshake wird geprüft, ob das Zertifikat der Gegenseite dazu passt. Wenn du die Fingerprints auf einem sicheren Weg (z. B. über einen authentifizierten Server oder per QR-Code) zusätzlich vergleichst, kannst du Man-in-the-Middle-Angriffe auf der Signalisierungsebene erkennen.
Typische Anwendungsfälle:
- Ein selbst erzeugtes Zertifikat (
RTCPeerConnection.generateCertificate()) identifizieren, bevor es in einer Verbindung eingesetzt wird. - Ein Zertifikat, das dauerhaft (z. B. in IndexedDB) gespeichert ist, über seinen Fingerprint einer Geräte- oder Benutzeridentität zuordnen.
- Fingerprints aus dem lokalen bzw. entfernten SDP mit den erwarteten Werten abgleichen.
Rückgabewert
{ algorithm: string, value: string }. algorithm ist der Name der Hashfunktion nach IANA (z. B. "sha-256"), value der Fingerprint als hexadezimale Zeichenkette in Kleinbuchstaben, z. B. "3a:5f:…". Meist enthält das Array genau einen Eintrag.Beispiele
Zertifikat erzeugen und Fingerprints ausgeben
const cert = await RTCPeerConnection.generateCertificate({
name: 'ECDSA',
namedCurve: 'P-256'
});
for (const { algorithm, value } of cert.getFingerprints()) {
console.log(`${algorithm}: ${value}`);
}
console.log('Gültig bis:', new Date(cert.expires).toISOString());
Fingerprint mit der a=fingerprint-Zeile im SDP abgleichen
const cert = await RTCPeerConnection.generateCertificate({
name: 'ECDSA',
namedCurve: 'P-256'
});
const pc = new RTCPeerConnection({ certificates: [cert] });
pc.createDataChannel('chat');
const offer = await pc.createOffer();
await pc.setLocalDescription(offer);
// Fingerprint aus dem SDP auslesen
const match = pc.localDescription.sdp.match(/a=fingerprint:(\S+) (\S+)/);
const [, sdpAlgo, sdpValue] = match;
const ok = cert.getFingerprints().some(
(fp) => fp.algorithm === sdpAlgo.toLowerCase() &&
fp.value === sdpValue.toLowerCase()
);
console.log('SDP passt zum Zertifikat:', ok);
Kurze Prüfsumme zum manuellen Vergleich anzeigen
// Zeigt einen gekürzten Fingerprint an, den Nutzer mündlich vergleichen können
const shortFingerprint = (cert) => {
const fp = cert.getFingerprints().find((f) => f.algorithm === 'sha-256');
return fp ? fp.value.split(':').slice(0, 4).join('').toUpperCase() : null;
};
const cert = await RTCPeerConnection.generateCertificate({
name: 'RSASSA-PKCS1-v1_5',
modulusLength: 2048,
publicExponent: new Uint8Array([1, 0, 1]),
hash: 'SHA-256'
});
console.log('Sicherheitscode:', shortFingerprint(cert));
// Wichtig · Fallstricke
- Browser-Kompatibilität: Firefox unterstützt die Methode schon lange. In Chromium-Browsern und Safari ist sie erst seit 2023 verfügbar. In älteren Versionen fehlt sie. Prüfe deshalb vorher mit
typeof cert.getFingerprints === 'function'und lies den Fingerprint sonst aus dem SDP aus. - Groß-/Kleinschreibung: Die Methode liefert Kleinbuchstaben. Im SDP stehen die Hex-Werte dagegen meist in Großbuchstaben. Vergleiche daher immer ohne Beachtung der Groß-/Kleinschreibung.
- Sicherheit: Ein Fingerprint schützt nur dann vor Man-in-the-Middle-Angriffen, wenn er über einen vertrauenswürdigen, authentifizierten Kanal verglichen wird. Wenn der Signalisierungsserver manipuliert ist, kann er SDP und Fingerprint gemeinsam austauschen.
- Ein
RTCCertificateläuft nachexpiresab. Ein neu erzeugtes Zertifikat hat auch einen neuen Fingerprint. Gespeicherte Fingerprints musst du daher bei einem Zertifikatswechsel aktualisieren. - Das zurückgegebene Array ist eine Kopie. Wenn du es änderst, hat das keine Auswirkung auf das Zertifikat.