Am implementat un schimb de chei asimetrice pentru a crea o cheie simetrică.
Întrebarea mea este mai mult una filozofică/legală în ceea ce privește responsabilitatea schimbului de chei și ce se întâmplă atunci când să spunem că este folosită o cheie cunoscută în mod obișnuit.
Aș dori să setez aceste variabile de bază:
- Clientul are cheia publică a serverului codificată în memorie
- Serverul are cheia privată codificată în memorie
- Există un hardcoded
nonce_size
- Există un hardcoded
public_key_size
- Există un hardcoded
mac_size
Pașii comunicării pentru schimb sunt următorii:
- După o conexiune TCP reușită, clientul generează o nouă cheie publică
client_pubkey
, își criptează propria cheie publică client_pubkey
folosind un nou nonce temp_nonce_1
și hardcoded server_pubkey
, și trimite un mesaj în care primii octeți sunt nonce, iar restul sunt codificați client_pubkey
(inclusiv mac-ul său). Aceasta are o dimensiune cunoscută de nonce_size + public_key_size + mac_size
.
- Serverul primește un mesaj, verificându-i dimensiunea exactă
nonce_size + public_key_size + mac_size
. Dacă este, presupune că este un schimb cheie. Decriptează cheia publică. Serverul generează apoi un nou cheie_simetrică
, și trimite înapoi un mesaj care conține un nou nonce tmp_nonce2
, și cheia simetrică + mac criptate folosind recepția client_pubkey
.
- Clientul primește acest mesaj, știe exact ce dimensiune ar trebui să aibă, altfel respinge. Clientul are acum o cheie simetrică de utilizat.
- Serverul și clientul comunică prin tastele simetrice.
Deci, iată încercarea mea de a înțelege de ce este sigur:
- În cazul în care octeții de gunoi aleatori sunt trimiși către server, serverul generează o cheie, criptează cheia folosind gunoi, creând mai mult gunoi și apoi o trimite. Deci, în realitate, am trimis mai mult gunoi și apoi pur și simplu nu primim niciodată un mesaj valid și, în cele din urmă, expirăm, închidem conexiunea. Singurul rău aici este timpul pierdut de CPU pentru câteva secunde.
- Clientul trimite în mod specific o cheie publică de doar zero (sau un alt set de biți evident, ca toate cele 1) și un nonce valid (sau zero). În acest caz, serverul tratează zero-urile ca o cheie publică și trimite o cheie simetrică criptată prin cheia publică zero. Cu toate acestea, acest lucru ar trebui să fie în continuare sigur, deoarece a avea cheia publică cu zerouri presupune că cunoașteți cheia privată din care provine cheia publică zero, ceea ce ar dura miliarde de ani pentru a face inginerie inversă, deci este încă sigur.
- Presupunând că clientul și serverul pot reporni acest proces la infinit (și nu există o limită de x-try pe server), presupunând cumva printr-un noroc incalculabil și prin trimiterea de octeți aleatoriu, are loc un schimb de chei și un mesaj valid cu orice date a fost serverul așteptarea este trimisă și analizată de server, ne aruncăm brațele în aer, deoarece este aproape imposibil și practic.
rahatul se întâmplă
.
- În acest caz, nu putem spune că cineva este răspunzător, nu? Serverul nu poate face nimic dacă știe că este un pachet rău intenționat.
- Chiar dacă am avea o limită de x-retry de 2 încercări, teoretic ar putea apărea chiar și la prima conexiune de la o adresă IP și, din nou, nu putem face nimic în acest sens.
Deci, practic, totul este securizat, deoarece se așteaptă ca baza primului mesaj să fie criptată de o cheie publică de care numai serverul ar trebui să cunoască cheia_privată corespunzătoare, nu? Și că în cazul în care ceva, cumva, reușește vreodată să treacă, rezultatul este aruncat la nedefinit?
Îmi pare rău dacă acest lucru este într-adevăr concis, încerc doar să verific atât înțelegerea mea a teoriei și să mă asigur că nu există nicio greșeală în implementarea unui astfel de protocol.