Haszowanie rozmyte (TLSH)

Każdy skrót ze strony Haszowanie i uwierzytelnianie wiadomości jest zbudowany tak, aby pojedynczy zmieniony bit dawał zupełnie niepowiązany skrót. TLSH (Trend Micro Locality Sensitive Hash) jest zbudowany, by robić coś odwrotnego: podobne dane wejściowe dają podobne skróty, a sgcTLSH_Diff ocenia, jak bardzo różnią się dwa skróty. Odpowiada na pytanie „jak bardzo podobne są te dwa pliki”, a nie „czy te dwa pliki są identyczne”, co czyni go przydatnym do klasteryzacji i wykrywania niemal identycznych danych, klasyfikowania rodzin złośliwego oprogramowania oraz odnajdywania dokumentów, które zostały skopiowane i lekko zmodyfikowane.

 

TLSH nie jest skrótem bezpieczeństwa. Nie używaj go do integralności ani uwierzytelniania.

 

Nie jest odporny na kolizje, a atakujący, który kontroluje dane wejściowe, może celowo sterować skrótem. Każda funkcja znajduje się w jednostce sgcCrypto_TLSH.

 

Obliczanie skrótu

 

Dane wejściowe muszą mieć co najmniej 50 bajtów (cTLSH_MinDataLength) i być na tyle zróżnicowane, by wypełnić ponad połowę wewnętrznych kubełków; skrót ma 72 znaki (cTLSH_DigestLength), zaczynając od prefiksu wersji T1. Dane wejściowe, które są zbyt krótkie albo zbyt jednorodne (na przykład długi ciąg jednego powtarzającego się bajtu), nie mają wystarczającego sygnału do scharakteryzowania, a poniższe funkcje zwracają wtedy pusty ciąg zamiast bezsensownego skrótu.

 


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;

 

Duży plik nie musi być trzymany w pamięci naraz; przepuść go przez interfejs strumieniowy w blokach albo przekaż strumień bezpośrednio do sgcTLSH_Stream:

 


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

 

Porównywanie dwóch skrótów

 


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

 

Zero (cTLSH_IdenticalDiff) oznacza ten sam skrót; wynik rośnie wraz z tym, jak bardzo różnią się dwa dane wejściowe, bez stałej górnej granicy. Nie ma uniwersalnego progu, skalibruj go na podstawie własnego korpusu danych, ale jako punkt wyjścia odległość poniżej mniej więcej 30 zwykle wskazuje tę samą lub niemal tę samą zawartość, podczas gdy wyższe wartości wskazują na coraz mniejsze pokrewieństwo. aLengthDiff wlicza do wyniku różnicę długości danych wejściowych; wyłącz go, porównując zawartość, która jest zasadnie dopełniona lub obcięta, na przykład pliki dziennika zrotowane przy różnych rozmiarach. Funkcja zwraca -1, jeśli którykolwiek ze skrótów jest źle sformułowany.