Atac de sincronizare - Timing attack

În criptografie , un atac de sincronizare este un atac pe canal lateral în care atacatorul încearcă să compromită un criptosistem analizând timpul necesar pentru a executa algoritmi criptografici. Fiecare operație logică dintr-un computer necesită timp pentru a se executa, iar timpul poate diferi în funcție de intrare; cu măsurători precise ale timpului pentru fiecare operație, un atacator poate lucra înapoi la intrare. Găsirea secretelor prin informații de sincronizare poate fi semnificativ mai ușoară decât utilizarea analizei criptografice a perechilor de text clar, criptare, cunoscute. Uneori, informațiile de sincronizare sunt combinate cu criptanaliza pentru a crește rata de scurgere a informațiilor.

Informațiile se pot scurge dintr-un sistem prin măsurarea timpului necesar pentru a răspunde la anumite întrebări. Cât de mult pot ajuta aceste informații un atacator depinde de multe variabile: proiectarea sistemului criptografic, procesorul care rulează sistemul, algoritmii utilizați, detalii de implementare asortate, contramăsurile de atac de sincronizare, acuratețea măsurătorilor de sincronizare etc. Atacurile de sincronizare pot fi aplicate la orice algoritm care are variație temporală dependentă de date. Eliminarea dependențelor de sincronizare este dificilă în unele algoritmi care utilizează operații de nivel scăzut care prezintă frecvent timp de execuție variat.

Atacurile de sincronizare sunt adesea trecute cu vederea în faza de proiectare, deoarece sunt atât de dependente de implementare și pot fi introduse neintenționat cu optimizări ale compilatorului . Evitarea atacurilor de sincronizare implică proiectarea funcțiilor în timp constant și testarea atentă a codului executabil final.

Evitare

Mulți algoritmi criptografici pot fi implementați (sau mascați de un proxy) într-un mod care reduce sau elimină informațiile de sincronizare dependente de date, un algoritm în timp constant . Luați în considerare o implementare în care fiecare apel către un subrutină revine întotdeauna în exact x secunde, unde x este timpul maxim necesar pentru a executa rutina respectivă la fiecare intrare autorizată posibilă. Într-o astfel de implementare, calendarul algoritmului este mai puțin probabil să scurgă informații despre datele furnizate acelei invocații. Dezavantajul acestei abordări este că timpul folosit pentru toate execuțiile devine cel al celei mai slabe performanțe a funcției.

Dependența de date a calendarului poate proveni din una dintre următoarele:

  • Acces non-local la memorie, deoarece CPU poate cache datele. Software-ul rulat pe un procesor cu o memorie cache de date va prezenta variații de sincronizare dependente de date ca rezultat al memorării în memoria cache.
  • Salturi condiționate . Procesoarele moderne încearcă să execute în mod speculativ sărituri trecute prin ghicire. Ghicirea greșită (nu neobișnuit cu datele secrete în esență aleatorii) implică o întârziere măsurabilă, pe măsură ce CPU încearcă să retragă. Acest lucru necesită scrierea unui cod fără ramuri .
  • Unele operații matematice „complicate”, în funcție de hardware-ul procesorului real:
    • Împărțirea întregului este aproape întotdeauna timp neconstant. CPU utilizează o buclă de microcod care folosește o cale de cod diferită atunci când divizorul sau dividendul este mic.
    • CPU-urile fără schimbător de cilindri execută schimbări și rotații într-o buclă, o poziție la un moment dat. Ca urmare, suma de transferat nu trebuie să fie secretă.
    • Procesoarele mai vechi rulează multiplicări într-un mod similar cu diviziunea.

Exemple

Timpul de execuție pentru algoritmul pătrat și multiplicat utilizat în exponențierea modulară depinde liniar de numărul de biți „1” din cheie. În timp ce numărul de biți „1” singuri nu este suficientă informație pentru a facilita găsirea cheii, se pot utiliza execuții repetate cu aceeași cheie și intrări diferite pentru a efectua analize statistice de corelație a informațiilor de sincronizare pentru a recupera cheia complet, chiar și printr-o atacator pasiv. Măsurătorile de sincronizare observate includ adesea zgomotul (din surse precum latența rețelei sau diferențele de acces la unitatea de disc de la acces la acces și tehnicile de corectare a erorilor utilizate pentru a se recupera de la erorile de transmisie). Cu toate acestea, atacurile de sincronizare sunt practice împotriva unui număr de algoritmi de criptare, inclusiv RSA , ElGamal și algoritmul de semnătură digitală .

În 2003, Boneh și Brumley au demonstrat un atac practic de sincronizare bazat pe rețea pe serverele web activate SSL , bazat pe o vulnerabilitate diferită care are legătură cu utilizarea RSA cu optimizări ale teoremei restului chinez . Distanța reală a rețelei a fost mică în experimentele lor, dar atacul a recuperat cu succes o cheie privată de server în câteva ore. Această demonstrație a condus la implementarea pe scară largă și utilizarea tehnicilor de orbire în implementările SSL. În acest context, orbirea este menită să elimine corelațiile dintre cheie și timpul de criptare.

Unele versiuni ale Unix utilizează o implementare relativ scumpă a funcției de bibliotecă criptă pentru a introduce o parolă de 8 caractere într-un șir de 11 caractere. Pe hardware-ul mai vechi, acest calcul a durat în mod deliberat și măsurabil: până la două sau trei secunde, în unele cazuri. Programul de autentificare în versiunile anterioare ale Unix a executat funcția criptă numai atunci când numele de autentificare a fost recunoscut de sistem. Aceste informații au scurs prin sincronizare cu privire la validitatea numelui de conectare, chiar și atunci când parola a fost incorectă. Un atacator ar putea exploata astfel de scurgeri aplicând mai întâi forța brută pentru a produce o listă de nume de autentificare cunoscute a fi valide, apoi să încerce să obțină acces combinând doar aceste nume cu un set mare de parole despre care se știe că sunt frecvent utilizate. Fără informații despre validitatea numelor de autentificare, timpul necesar pentru a executa o astfel de abordare ar crește cu ordinele de mărime, făcându-l efectiv inutil. Versiunile ulterioare ale Unix au remediat această scurgere executând întotdeauna funcția criptă, indiferent de validitatea numelui de autentificare.

Două procese izolate altfel în siguranță , care rulează pe un singur sistem, fie de memorie cache sau memorie virtuală poate comunica prin provocarea în mod deliberat erori de pagini și / sau ratări cache într - un singur proces, apoi monitorizarea schimbărilor care rezultă în perioadele de acces de la celălalt. La fel, dacă o aplicație este de încredere, dar paginarea / cache-ul acesteia este afectată de logica de ramificare, poate fi posibil ca o a doua aplicație să determine valorile datelor în comparație cu starea ramificării prin monitorizarea modificărilor timpului de acces; în exemple extreme, acest lucru poate permite recuperarea biților de cheie criptografică.

Atacurile Meltdown și Spectre din 2017 care au forțat producătorii de procesoare (inclusiv Intel, AMD, ARM și IBM) să-și reproiecteze procesoarele, ambele se bazează pe atacuri de sincronizare. La începutul anului 2018, aproape fiecare sistem informatic din lume este afectat de Spectre, ceea ce îl face cel mai puternic exemplu de atac de sincronizare din istorie.

Algoritm

Următorul cod C demonstrează o comparație tipică de șir nesigur care încetează testarea imediat ce un caracter nu se potrivește. De exemplu, atunci când se compară „ABCDE” cu „ABxDE” va reveni după 3 iterații de buclă:

bool insecureStringCompare(const void *a, const void *b, size_t length) {
  const char *ca = a, *cb = b;
  for (size_t i = 0; i < length; i++)
    if (ca[i] != cb[i])
      return false;
  return true;
}

Prin comparație, următoarea versiune rulează în timp constant, testând toate caracterele și folosind o operație pe biți pentru a acumula rezultatul:

bool constantTimeStringCompare(const void *a, const void *b, size_t length) {
  const char *ca = a, *cb = b;
  bool result = true;
  for (size_t i = 0; i < length; i++)
    result &= ca[i] == cb[i];
  return result;
}

În lumea funcțiilor bibliotecii C, prima funcție este analogă memcmp(), în timp ce cea din urmă este analogă cu NetBSD consttime_memequal()sau OpenBSD timingsafe_bcmp()și timingsafe_memcmp. Pe alte sisteme, funcția de comparație din bibliotecile criptografice, cum ar fi OpenSSL și libsodium, poate fi utilizată.

Note

Atacurile de sincronizare sunt mai ușor de montat dacă adversarul cunoaște internele implementării hardware și, cu atât mai mult, sistemul criptografic utilizat. Deoarece securitatea criptografică nu ar trebui să depindă niciodată de obscuritatea oricăreia dintre ele (a se vedea securitatea prin obscuritate , în special atât principiul lui Shannon Maxim, cât și principiul lui Kerckhoffs ), nici rezistența la atacurile de sincronizare nu ar trebui. Dacă nu altceva, un exemplar poate fi achiziționat și inversat. Atacurile de sincronizare și alte atacuri cu canale laterale pot fi, de asemenea, utile în identificarea sau, eventual, ingineria inversă, a unui algoritm criptografic utilizat de un dispozitiv.

Referințe

Lecturi suplimentare