Signatur
Beschreibung
Die Eigenschaft fingerprintAlgorithm gehört zu RTCCertificateStats. Solche Objekte liefert RTCPeerConnection.getStats() mit type === "certificate", und zwar für jedes Zertifikat, das beim DTLS-Handshake einer WebRTC-Verbindung verwendet wird. Das kann das lokale oder das entfernte Zertifikat sein. Der Wert ist der Name der Hash-Funktion, mit der der Fingerabdruck in fingerprint berechnet wurde, zum Beispiel "sha-256".
Die Namen stammen aus dem IANA-Register „Hash Function Textual Names“ (RFC 4572 / RFC 8122). Es sind dieselben Bezeichner, die im SDP in der Zeile a=fingerprint:sha-256 AB:CD:… stehen. Moderne Browser verwenden praktisch immer "sha-256".
Nützlich ist die Eigenschaft vor allem für Diagnose und Sicherheit: Man kann prüfen, ob ein ausreichend starker Hash-Algorithmus benutzt wird. Außerdem kann man den Fingerabdruck der Gegenstelle über einen zweiten, unabhängigen Kanal abgleichen (etwa per Signalisierungsserver oder QR-Code), um Man-in-the-Middle-Angriffe zu erkennen.
Rückgabewert
"sha-256", "sha-384" oder "sha-512". Diese Schreibweise gilt laut Spezifikation und wird in der Praxis so geliefert.Beispiele
Hash-Algorithmen aller Zertifikate ausgeben
const pc = new RTCPeerConnection();
pc.createDataChannel('test');
const offer = await pc.createOffer();
await pc.setLocalDescription(offer);
// Hinweis: certificate-Statistiken erscheinen meist erst nach dem DTLS-Handshake
const stats = await pc.getStats();
stats.forEach((report) => {
if (report.type === 'certificate') {
console.log(report.id, report.fingerprintAlgorithm, report.fingerprint);
}
});
Schwache Hash-Algorithmen erkennen
const STARKE_ALGORITHMEN = new Set(['sha-256', 'sha-384', 'sha-512']);
const pruefeZertifikate = async (pc) => {
const stats = await pc.getStats();
const warnungen = [];
for (const report of stats.values()) {
if (report.type !== 'certificate') continue;
const algo = report.fingerprintAlgorithm?.toLowerCase();
if (!STARKE_ALGORITHMEN.has(algo)) {
warnungen.push(`Unsicherer Algorithmus: ${algo} (${report.id})`);
}
}
return warnungen;
};
// Aufruf, sobald die Verbindung steht
pc.addEventListener('connectionstatechange', async () => {
if (pc.connectionState === 'connected') {
console.log(await pruefeZertifikate(pc));
}
});
Fingerabdruck der Gegenstelle mit SDP abgleichen
const vergleicheRemoteFingerprint = async (pc) => {
const stats = await pc.getStats();
const transport = [...stats.values()].find((r) => r.type === 'transport');
const remoteCert = transport && stats.get(transport.remoteCertificateId);
if (!remoteCert) return false;
// Erwartete Zeile im SDP: a=fingerprint:<algorithmus> <wert>
const sdp = pc.remoteDescription.sdp;
const erwartet = `a=fingerprint:${remoteCert.fingerprintAlgorithm} ${remoteCert.fingerprint}`;
return sdp.toLowerCase().includes(erwartet.toLowerCase());
};
console.log(await vergleicheRemoteFingerprint(pc));
// Wichtig · Fallstricke
- Zeitpunkt: Einträge vom Typ
certificateerscheinen ingetStats()meist erst, wenn der DTLS-Transport aufgebaut ist. Davor findet man oft keinen passenden Eintrag. - Schreibweise: Im SDP kann der Algorithmus je nach Gegenstelle großgeschrieben sein (
SHA-256). Vergleiche deshalb am besten unabhängig von Groß- und Kleinschreibung. - Nur lesbar: Der Wert ist eine reine Statistikangabe und lässt sich nicht ändern. Welcher Algorithmus zum Einsatz kommt, legt der Browser fest. Über
RTCPeerConnection.generateCertificate()wählst du nur den Schlüsselalgorithmus (ECDSA/RSA), nicht den Hash für den Fingerabdruck. - Sicherheit: Einen Man-in-the-Middle-Angriff erkennt der Fingerabdruck nur, wenn er über einen vertrauenswürdigen Kanal abgeglichen wird. Die Signalisierung selbst muss abgesichert sein, zum Beispiel über HTTPS oder WSS.
- Kompatibilität: Wird in aktuellen Versionen von Chromium, Firefox und Safari unterstützt. Ältere Browser liefern eventuell gar keine
certificate-Statistiken. Greife deshalb defensiv zu, etwa mit?..