Fuzzy Hashing (TLSH)

Jeder Hash auf der Seite Hashing & Nachrichtenauthentifizierung ist so aufgebaut, dass ein einziges geändertes Bit einen völlig unabhängigen Digest erzeugt. TLSH (Trend Micro Locality Sensitive Hash) ist so aufgebaut, dass es das Gegenteil tut: Ähnliche Eingaben erzeugen ähnliche Digests, und sgcTLSH_Diff bewertet, wie weit zwei Digests auseinanderliegen. Es beantwortet „wie ähnlich sind sich diese beiden Dateien" statt „sind diese beiden Dateien identisch", was es nützlich macht für Clustering und die Erkennung nahezu identischer Duplikate, die Triage von Malware-Familien und das Auffinden von Dokumenten, die kopiert und leicht bearbeitet wurden.

 

TLSH ist kein Sicherheits-Hash. Verwenden Sie ihn nicht für Integrität oder Authentifizierung.

 

Er ist nicht kollisionsresistent, und ein Angreifer, der die Eingabe kontrolliert, kann den Digest gezielt steuern. Jede Funktion befindet sich in sgcCrypto_TLSH.

 

Einen Digest berechnen

 

Die Eingabe muss mindestens 50 Byte umfassen (cTLSH_MinDataLength) und ausreichend variiert sein, um mehr als die Hälfte der internen Buckets zu füllen; ein Digest ist 72 Zeichen lang (cTLSH_DigestLength), beginnend mit dem Versionspräfix T1. Eine Eingabe, die zu kurz oder zu gleichförmig ist (zum Beispiel eine lange Folge desselben wiederholten Bytes), hat nicht genug Signal, um charakterisiert zu werden, und die folgenden Funktionen geben einen leeren String zurück statt eines bedeutungslosen Digests.

 


function sgcTLSH(const aData: TBytes): string;
function sgcTLSH_Stream(aStream: TStream): string;
function sgcTLSH_IsValid(const aDigest: string): Boolean;

var
  vDigest: string;
begin
  vDigest := sgcTLSH(oFileBytes);
  if vDigest = '' then
    { too short or too uniform to characterize }
  else
    { vDigest is a 72-character T1... string };
end;

 

Eine große Datei muss nicht auf einmal im Speicher gehalten werden; führen Sie sie in Blöcken durch die Streaming-Schnittstelle, oder übergeben Sie einen Stream direkt an sgcTLSH_Stream:

 


procedure sgcTLSH_Init(var aContext: TsgcTLSHContext);
procedure sgcTLSH_Update(var aContext: TsgcTLSHContext; const aData: TBytes);
function sgcTLSH_Final(var aContext: TsgcTLSHContext): string;

 

Zwei Digests vergleichen

 


function sgcTLSH_Diff(const aLeft, aRight: string; aLengthDiff: Boolean = True): Integer;

 

Null (cTLSH_IdenticalDiff) bedeutet denselben Digest; der Wert wächst mit der Unterschiedlichkeit der beiden Eingaben, ohne feste Obergrenze. Es gibt keinen universellen Schwellenwert, kalibrieren Sie ihn an Ihrem eigenen Korpus, aber als Ausgangspunkt deutet eine Distanz unter etwa 30 üblicherweise auf denselben oder nahezu denselben Inhalt hin, während höhere Werte auf zunehmend geringere Verwandtschaft hindeuten. aLengthDiff lässt den Unterschied in der Eingabelänge in den Wert einfließen; schalten Sie es aus, wenn Sie Inhalte vergleichen, die legitim aufgefüllt oder gekürzt sind, etwa Logdateien, die bei unterschiedlichen Größen rotiert wurden. Die Funktion gibt -1 zurück, wenn einer der beiden Digests fehlerhaft ist.