Dacă sunteți un utilizator de criptografie: toate acestea sunt învechite. Nu există niciun motiv în zilele noastre să combinați un MAC sau hash cu criptarea. Utilizați un standard AEAD algoritm, care combină confidențialitatea și protecția autenticității într-un mod care a fost verificat de criptografi. Ar putea folosi MAC-apoi-criptare, criptare-apoi-MAC sau criptare-și-MAC sub capotă, sau ceva care nu se potrivește în niciunul dintre aceste trei cadre, dar nu trebuie să-ți pese.
Dacă sunteți un designer de primitive criptografice: toate acestea sunt modalități potențiale de a oferi criptare autentificată. Criptarea autentificată a unui mesaj garantează două proprietăți: confidențialitatea (doar entitățile care au cheia secretă pot recupera mesajul din textul cifrat) și autenticitatea (doar entitățile care au cheia secretă pot crea un text cifrat valid).
Un MAC garantează autenticitatea. Criptarea garantează confidențialitatea în anumite ipoteze (criptarea fără autenticitate poate fi vulnerabilă la atacurile oracle, de exemplu umplutura atacurilor oracolului împotriva modului popular CBC). Puteți combina o primitivă MAC M
cu o primitivă de criptare E
pe un mesaj m
în diferite moduri (||
este concatenare):
E(M) || M(E(m))
: criptare-apoi-MAC. Criptați mesajul și adăugați MAC-ul de criptare.
E(m || M(m))
: MAC-apoi-criptare. Adăugați MAC-ul mesajului la mesaj și criptați rezultatul.
E(M) || M(m)
: criptare-și-MAC. Criptați mesajul și adăugați MAC-ul mesajului original.
Este posibil ca fiecare dintre ei să fie corect. De asemenea, este posibil să greșiți fiecare dintre ele. Pentru o revizuire a avantajelor și dezavantajelor fiecărei abordări, citiți Ar trebui să criptăm MAC-atunci sau criptăm-apoi-MAC?
Hash-then-encrypt este același lucru cu MAC-then-encrypt, cu excepția faptului că folosește o funcție hash în loc de MAC: E(M || H(h))
. Acest lucru are șanse mari de a garanta confidențialitatea, deoarece totul este criptat. Autenticitatea este mai fragilă: se bazează pe faptul că adversarul nu poate crea criptarea hash-ului. Nu cunosc o construcție funcțională care să folosească acest cadru, dar este posibil să existe una.
Întrebare bonus: de ce nu criptați-apoi-hash sau criptați-și-hash?
Acestea nu pot funcționa. Criptare-apoi-hash (E(m) || Tiv))
) permite oricui să falsifice mesaje arbitrare doar creând un text cifrat și adăugându-i hash. (Și adversarul poate chiar să cunoască conținutul mesajului; de exemplu, trunchierea unui text cifrat corespunde adesea trunchierii unui mesaj, astfel încât un adversar poate trunchia liber un mesaj existent.) Criptare și hash (E(m) || H(m)
) dezvăluie hash-ul mesajului, astfel încât oricine poate cel puțin să ghicească care ar putea fi mesajul și să-și verifice presupunerea.