Lucrez cu o echipă de dezvoltatori care implementează criptarea în repaus la nivel de aplicație. Este pentru câmpuri deosebit de sensibile din interiorul unui RDB. (Stocarea DB de bază are un strat suplimentar de criptare, dar acesta este în afara subiectului aici.) Utilizăm un Spring's AesBytesEncryptor și clase aferente pentru asta.
Nu am rezolvat încă pe deplin rotația cheilor și investighez cum să o fac într-un mod sigur. Am dori să folosim un instrument separat de rotație a tastelor care ar rula izolat de aplicația care consumă datele. Acest instrument de rotație a cheilor va accesa DB asincron și va efectua recriptarea în bucăți mici. (Nu într-o singură tranzacție DB care ar recripta toate datele.)
Pentru a face acest lucru, plănuim ca aplicația să poată fi configurată cu mai multe (ei bine, două) chei în același timp. Ar folosi întotdeauna prima cheie pentru a cripta datele noi. Dar ar putea decripta datele vechi cu oricare dintre chei, în funcție de dacă instrumentul de rotație a cheilor a re-criptat deja câmpul respectiv.
Acum întrebarea este dacă trebuie să stocăm metadate suplimentare de versiuni ale cheilor în DB? Aceasta ar spune aplicației ce cheie de decriptare să folosească pentru orice bucată de date.
Sper să ocolesc asta bazându-mă în schimb pe o sumă de verificare a formularelor. Aplicația ar încerca doar cheile de decriptare pe rând, până când obține o valoare decriptată care nu rupe suma de control.
Imho, AesBytesEncryptor de la Spring ar putea să ofere deja tot ceea ce avem nevoie. Dar fiabilitatea va depinde de modul pe care îl folosim. Iată părerile mele despre cele două moduri acceptate:
Modul AES/CBC/PKCS5Padding:
Nu are o sumă de control per-se, dar umplutura se va rupe probabil când încercați decriptarea cu cheia greșită. Totuși, aceasta depinde de dimensiunea căptușelii, care depinde de dimensiunea datelor de text simplu. În cel mai rău caz, ar putea exista doar 1 octet de umplutură. Așadar, șansele de a atinge umplutura corectă cu cheia de decriptare greșită ar putea fi de până la 1/256. Asta pare prea riscant pentru a te baza.
Mod AES/GCM/NoPadding:
Aici „eticheta de autentificare” GCM servește ca o formă de sumă de control. Din câte am înțeles, este întotdeauna 128 de biți (16 octeți) pentru AES. Aceasta înseamnă că șansele de a atinge o etichetă de autentificare validă cu cheia de decriptare greșită sunt de aproximativ 1/(2^128).Asta practic nu este niciodată, așa că cred că ar trebui să fie potrivit pentru aplicația noastră.
Sunt corecte ipotezele de mai sus? Ce am greșit?
Crezi că este suficient de robust pentru a încerca mai multe chei de decriptare pe rând în timpul rotației cheilor, când folosești AES/GCM/NoPadding? Sau trebuie să stocăm informațiile de versiuni ale cheilor alături de datele criptate până la urmă?
Sau, există o modalitate și mai bună de a rezolva rotația cheilor în scenariul nostru?