Saltar al contenido principal
de/blog/obscura/research/audio-fingerprinting/

obscura/research/audio-fingerprinting

2 Min. Lesezeit

Übersicht

Audio-Fingerprinting verwendet die Web Audio API (AudioContext), um einen eindeutigen Identifikator zu erzeugen, der darauf basiert, wie die Audio-Hardware und -Software des Geräts ein generiertes Signal verarbeitet.

Mechanismus

  1. Ein AudioContext wird erstellt
  2. Ein Oszillatorsignal wird generiert (Sinuswelle bei einer bestimmten Frequenz)
  3. Verarbeitung durch DynamicsCompressorNode
  4. Das verarbeitete Signal wird über getChannelData() extrahiert
  5. Das resultierende Gleitkomma-Array wird gehasht
const ctx = new AudioContext()
const osc = ctx.createOscillator()
const compressor = ctx.createDynamicsCompressor()
osc.connect(compressor)
compressor.connect(ctx.destination)

// Compressor-Einstellungen
compressor.threshold.value = -50
compressor.knee.value = 40
compressor.ratio.value = 12
compressor.reduction.value = -20
osc.frequency.value = 1000
osc.type = 'sawtooth'

// Verarbeiten und extrahieren
const analyser = ctx.createAnalyser()
const buffer = new Float32Array(analyser.fftSize)
analyser.getFloatFrequencyData(buffer)
const hash = md5(buffer) // einzigartig pro Audio-Stack

Entropiequellen

Quelle Variabilität
Audio-Treiber und -Hardware Hoch
Abtastratenunterstützung Mittel
Dynamikverarbeitungs-Implementierung Mittel
Betriebssystem-Audio-Stack (PulseAudio, ALSA, CoreAudio, WASAPI) Hoch
Audio-Kanalanzahl Niedrig

Abschwächung

Auf Proxy-Ebene

Der AudioContext läuft vollständig im Browser – der Proxy kann seine Ausgabe nicht ändern.

Per injiziertem JS

AudioContext.prototype.getChannelData oder AnalyserNode.prototype.getFloatFrequencyData überschreiben, um generische/glatte Daten zurückzugeben.

// Injizierte Überschreibung
const originalGetFloatFrequencyData = AnalyserNode.prototype.getFloatFrequencyData
AnalyserNode.prototype.getFloatFrequencyData = function(array) {
  originalGetFloatFrequencyData.call(this, array)
  // Ausgabe glätten/verrauschen
  for (let i = 0; i < array.length; i++) {
    array[i] = -100 // glattes Signal
  }
}

Problem: Die Website kann Manipulation erkennen, indem sie prüft, ob die Ausgabe im Vergleich zur echten Hardwareausgabe zu gleichmäßig ist.

Schlussfolgerungen

  • Audio-Fingerprinting ist CPU-/OS-/Hardware-spezifisch
  • Kann auf Proxy-Ebene nicht gespooft werden
  • JS-Injection kann es abschwächen, aber nicht vollständig unterbinden
  • Bester Ansatz: Überschreibung + konsistentes Rauschen per injiziertem JS