Puncte:1

Cum să compun mai multe valori pentru autentificarea MAC?

drapel sr

Dacă datele pe care vreau să le autentific constă din mai multe valori și calculez un MAC pur și simplu concatenând valorile, un adversar poate „schimba” caracterele în acele valori fără a invalida MAC-ul. Cum este această problemă frecvent și cel mai bine abordată?

Am gasit această întrebare existentă despre MACing mai multe mesaje, dar simt că soluțiile propuse nu se generalizează bine pentru mai mult de două mesaje.

Luați în considerare următorul exemplu artificial:

Să presupunem că am un server care stochează intrări de jurnal autentice pentru clienți. Clientul scrie o intrare de jurnal, o autentifică folosind un MAC și o trimite la server. Mai târziu, când clientul preia intrările de jurnal de pe server, ar trebui să poată verifica autenticitatea acestora.

Să presupunem că intrările de jurnal au următoarea structură:

{
  creat la: "1621012345",
  mesaj: „prima intrare”
}

Naiv, aș putea crea un MAC pentru o intrare de jurnal l la fel de $$ mac = \text{HMAC}(K, l.createdAt \| l.message) $$ Unde $\|$ denotă concatenare şi $K$ este cheia secretă.

Dacă ar fi să stochez această intrare de jurnal și MAC pe un server și să o recuperez mai târziu, serverul ar putea reveni

{
  creat la: "1621012",
  mesaj: „345prima intrare”,
  mac: „<MAC-ul calculat mai sus>”
}

De cand 1621012 || 345prima intrare este la fel ca 1621012345 || prima intrare Nu aș observa manipularea la verificarea MAC-ului.

Rețineți că, în acest caz, ar trebui să detectez de fapt manipularea validând apoi lungimea creat la. Dar asta funcționează doar dacă lungimea este fixă ​​și nu dacă aș avea, să zicem, numele autorului în loc de marcajul de timp.

Mă pot gândi la următoarele moduri de a trata acest lucru:

1. Intercalați un delimitator

Dacă mi-am calculat MAC ca $mac = \text{HMAC}(K, l.createdAt \| \text{':'} \| l.message)$ Cred că acest atac nu ar mai fi posibil. La prima vedere pare problematic faptul că caracterul delimitator poate apărea în mesaj. Dar asta face doar imposibilă reconstruirea fără ambiguitate a valorilor din șirul concatenat, ceea ce este irelevant în acest scenariu. Nu mă pot gândi la vreo modalitate de a face calculul MAC ambiguu aici. Este sigură această soluție simplă?

2. Valori hash înainte de concatenare

Aș putea calcula MAC-ul, de exemplu, ca $mac = \text{HMAC}(K, \text{SHA256}(l.createdAt) \| \text{SHA256}(l.message))$ (sau orice altă funcție hash criptografică). Acest lucru asigură că un adversar nu poate manipula în mod semnificativ valorile pe care le concatenez. De asemenea, se asigură că valorile concatenate au întotdeauna o lungime fixă. Hashing-ul adaugă vreo valoare în comparație cu prima idee?

3. Autentificați toate datele structurate

De asemenea, aș putea calcula MAC-ul peste obiectul JSON complet al intrării de jurnal. În mod efectiv, asta înseamnă că am delimitatori mai elaborați și semnificativi (cheile și sintaxa). Practic, ca un JWT. Rețineți că această abordare are și unele dezavantaje, care se rezumă în principal la pierderea flexibilității API și la necesitatea de a canoniza JSON. Există o postare grozavă pe blog despre asta la https://latacora.micro.blog/2019/07/24/how-not-to.html.


Îmi lipsesc vreo soluție bună pentru această problemă? Există o modalitate recomandată de a face față acestui lucru?

poncho avatar
drapel my
O soluție alternativă ar fi să adăugați înainte fiecare intrare cu lungimea sa; de exemplu. $HMAC_k( len(createdAT) | createdAT | len(mesaj) | mesaj )$. Desigur, aveți nevoie de o modalitate canonică de a converti lungimea într-un șir de octeți; de exemplu. convertiți-l întotdeauna într-o valoare little-endian de 4 octeți...
leftfold avatar
drapel sr
Buna observatie! L-am uitat pe acesta. Am citit [că ethereum obișnuia să facă asta](https://medium.com/mycrypto/the-magic-of-digital-signatures-on-ethereum-98fe184dc9c7) și apoi am schimbat în `32 || Keccak256(message)` (deoarece hash-ul este întotdeauna de 32 de octeți). Din păcate, motivația acestei schimbări nu îmi este clară din articol.
poncho avatar
drapel my
Celălalt lucru pe care trebuie să îl includeți în MAC sunt etichetele de câmp; dacă atacatorul este capabil să convertească „createdAT: time” în „deleteBY : time”, ei bine, asta este ceva ce am dori să detectăm...
leftfold avatar
drapel sr
Adevărat, deși depinde de cazul de utilizare și de modul în care clientul face validarea. Îmi imaginez că atunci când clientul calculează MAC-ul pentru validare, caută `l.createdAt` și folosește acea valoare pentru MAC. Dacă nu există câmp „createdAt”, atunci obiectul primit de la server este deja invalid. („deletedBy” este potențial ignorat atunci.) Acestea fiind spuse, dacă vrem să considerăm întregul JSON ca un „document”, atunci ar trebui să includem etichetele. Cred că acest lucru este foarte aproape de canonizarea și autentificarea întregului JSON, așa cum este subliniat în a treia idee.
Maarten Bodewes avatar
drapel in
Pentru intrările de jurnal aș MAC mesajele canonizate separat, dar aș include un contor. Oricum, veți dori să aveți o înregistrare centralizată și nu aș dori să includ un contor sub nanosecunde sau să efectueze trucuri, cum ar fi așteptarea de cel puțin o nanosecundă înainte de a continua. Dacă sincronizarea este o problemă, puteți include un ID de serviciu sau ceva similar. Bazele de date sunt bune la astfel de lucruri.
Puncte:0
drapel sr

Pentru a răspunde parțial la propria mea întrebare aici: ideea 1 nu este de fapt sigură.

Devine problematic dacă delimitatorul apare în valoare până la urmă. Considera folosind , ca delimitator pentru valori Buna ziua, și Lume. Intercalate cu , Asta da Salut Lume, unde prima virgulă face parte din mesaj, iar a doua este delimitătorul. Din păcate, valorile Buna ziua și ,Lume da acelasi mesaj. Deci intuiția că mesajul compus ar trebui să fie analizabil pare să existe până la urmă.

După cum a subliniat @poncho în comentarii, acest lucru ar putea fi remediat prin predarea lungimii câmpului fiecărui câmp, în loc să se utilizeze delimitatori.

Personal, probabil că voi merge cu a doua versiune (hashing valorile înainte de concatenare). Dar tot aș fi interesat dacă altcineva s-a confruntat cu asta și cum ați rezolvat-o.

Postează un răspuns

Majoritatea oamenilor nu înțeleg că a pune multe întrebări deblochează învățarea și îmbunătățește legătura interpersonală. În studiile lui Alison, de exemplu, deși oamenii își puteau aminti cu exactitate câte întrebări au fost puse în conversațiile lor, ei nu au intuit legătura dintre întrebări și apreciere. În patru studii, în care participanții au fost implicați în conversații ei înșiși sau au citit transcrieri ale conversațiilor altora, oamenii au avut tendința să nu realizeze că întrebarea ar influența – sau ar fi influențat – nivelul de prietenie dintre conversatori.