This is an old revision of the document!
Prezentarea PowerPoint pentru acest laborator o puteți găsi aici.
În acest exercițiu vom folosi CLI pentru a calcula un HMAC, cu SHA-1 pentru algoritmul de hash.
Aduceți-vă aminte de la curs că pentru ca un HMAC să fie sigur, avem nevoie să generăm o cheie aleatoare $k \gets \mathcal{K}$.
Putem folosi octeți aleatori folosind openssl rand
. Modul în care se generează HMAC-uri îl puteți găsi în documentația pentru openssl dgst
.
Pentru acest exercițiu, folosiți comenzi OpenSSL pentru:
Înainte de a începe următorul exercițiu, descărcați arhiva laboratorului de aici.
Arhiva conține codul sursă pentru Exercițiul 3, dar din păcate este criptat. Aveți noroc că am uitat să scoatem fișierul cu parola din arhivă.
Folosiți comenzi openssl
pentru a decripta fișierul cu codul sursă.
În acest exercițiu vom folosi OpenSSL ca să criptăm și să decriptăm cu AES-256-GCM. Din păcate, AES-GCM nu poate fi folosit prin comenzile din CLI de OpenSSL, așa că va trebui să îl implementăm noi.
Deschideți fișierul pe care l-ați decriptat la exercițiul anterior și analizați codul. Sunt două funcții care trebuie implementate: aes_gcm_encrypt
și aes_gcm_decrypt
. Am pus comentarii în cod care să vă îndrume în implementare.
Funcția main inițializează o cheie dummy și un IV dummy; un mesaj lung este criptat și apoi decriptat. Mesajul criptat ar trebui să includă automat la finalul ei tag-ul de autentificare, iar decriptarea ar trebui să întoarcă o eroare dacă verificarea tag-ului eșuează.
Dacă nu schimbați cheile și implementarea este corectă, textul criptat pe care îl obțineți ar trebui să fie același cu al nostru. În caz contrar, unele teste vor pica.
Aveți mai jos inclus un exemplu de criptare cu RC2 (luat din paginile de manual ale OpenSSL). Criptarea AES-GCM este similară ca implementare - tag-ul de autentificare este automat adăugat când finalizăm contextul criptării.
int do_crypt(FILE *in, FILE *out, int do_encrypt) { /* Allow enough space in output buffer for additional block */ inbuf[1024], outbuf[1024 + EVP_MAX_BLOCK_LENGTH]; int inlen, outlen; /* Bogus key and IV: we'd normally set these from * another source. */ unsigned char key[] = "0123456789"; unsigned char iv[] = "12345678"; /* Don't set key or IV because we will modify the parameters */ EVP_CIPHER_CTX_init(&ctx); EVP_CipherInit_ex(&ctx, EVP_rc2(), NULL, NULL, NULL, do_encrypt); EVP_CIPHER_CTX_set_key_length(&ctx, 10); /* We finished modifying parameters so now we can set key and IV */ EVP_CipherInit_ex(&ctx, NULL, NULL, key, iv, do_encrypt); for(;;) { inlen = fread(inbuf, 1, 1024, in); if(inlen <= 0) break; if(!EVP_CipherUpdate(&ctx, outbuf, &outlen, inbuf, inlen)) { /* Error */ EVP_CIPHER_CTX_cleanup(&ctx); return 0; } fwrite(outbuf, 1, outlen, out); } if(!EVP_CipherFinal_ex(&ctx, outbuf, &outlen)) { /* Error */ EVP_CIPHER_CTX_cleanup(&ctx); return 0; } fwrite(outbuf, 1, outlen, out); EVP_CIPHER_CTX_cleanup(&ctx); return 1; }