HotXLS scrie un bloc dataIntegrity conform în pachetele XLSX criptate Agile și îl verifică la deschidere. HMAC-SHA-512 acoperă întregul stream EncryptedPackage, inclusiv prefixul său StreamSize de opt bytes, și este verificat asupra textului cifrat înainte ca vreun segment să fie decriptat, astfel încât o parolă greșită sau un pachet modificat este detectat, nu decriptat în date fără sens
Criptarea fără integritate este un răspuns pe jumătate, iar formatele de fișier Office fac ca acest gol să fie ușor de trecut cu vederea, pentru că din exterior criptarea pare foarte temeinică. Înțelegerea a ceea ce promite fiecare strat este ce menține scurtă o revizuire de securitate
Ce promite de fapt un registru de lucru criptat?
Criptarea Agile, definită în [MS-OFFCRYPTO], îți oferă confidențialitate prin AES în modul CBC, cu o cheie derivată dintr-un hash de parolă SHA-512 iterat. Confidențialitatea este toată promisiunea acelei construcții. CBC nu este un mod autentificat: nu spune nimic despre dacă textul cifrat pe care îl decriptezi este textul cifrat care a fost scris
Consecința practică este specifică. Inversează biți într-un pachet criptat, iar CBC îi va decripta bucuros în alt text simplu. De obicei vei obține o eroare de parsare ZIP undeva mai departe în lanț, pentru că un stream deflate corupt rareori supraviețuiește, dar cuvântul „de obicei” face multă muncă în acea propoziție, iar o eroare de parser din aval este un loc groaznic în care să afli că un fișier a fost modificat. Elementul dataIntegrity există pentru a răspunde direct la întrebare, înainte de decriptare, cu un MAC peste bytes exacți
Cum rulează verificarea, și în ce ordine
Ordinea este partea interesantă. HotXLS derivă cheia intermediară din parolă, decriptează cheia HMAC criptată și valoarea HMAC din atributele dataIntegrity folosind IV-uri derivate din block-key, calculează HMAC-SHA-512 peste pachetul criptat așa cum este stocat, și compară. Abia apoi începe decriptarea segmentelor
Verificarea MAC-ului peste textul cifrat, nu peste textul simplu, este disciplina standard encrypt-then-MAC, și este ceea ce face verificarea semnificativă: un pachet modificat este respins fără ca vreun byte controlat de atacator să fi trecut prin traseul de decriptare și inflate. Ambele comparații din traseul de deschidere, hash-ul verificator de parolă și valoarea HMAC, acumulează diferențele cu XOR și OR pe tot digest-ul, în loc să se întoarcă devreme la primul byte nepotrivit, astfel încât niciuna nu scurge o poziție de byte prin timing
var
Book: TXLSXWorkbook;
begin
Book := TXLSXWorkbook.Create;
try
// Funcționează pentru fișiere simple, criptate Standard și criptate Agile
if Book.OpenEncrypted('incoming.xlsx', PasswordFromVault) = 1 then
ProcessWorkbook(Book)
else
// Parolă greșită, sau un pachet al cărui HMAC dataIntegrity nu s-a potrivit
Quarantine('incoming.xlsx');
except
on E: Exception do
Quarantine('incoming.xlsx: ' + E.Message);
end;
Book.Free;
end;
Pe partea de scriere nu se schimbă nimic în codul tău. SaveAsEncrypted emite blocul automat, iar salt-urile, intrarea verificatorului și cheia HMAC provin din CryptGenRandom. Dacă acel apel eșuează, HotXLS ridică o excepție în loc să recurgă la o sursă mai slabă. Un CSPRNG fail-closed nu este paranoia; o degradare silențioasă la o sursă aleatorie predictibilă produce fișiere care arată criptate, trec fiecare test funcțional și sunt fără valoare
De ce fișierele fără bloc se deschid totuși?
Pentru că foarte multe registre de lucru criptate Agile aflate în circulație au fost scrise de producători care omit complet dataIntegrity, iar respingerea lor ar strica mult mai multă muncă legitimă decât ar proteja. HotXLS tratează integritatea ca prezentă doar atunci când ambele atribute, cheia HMAC criptată și valoarea HMAC criptată, sunt acolo și bine formate. Altfel verificarea este omisă, iar fișierul se deschide ca înainte
Aceasta este o decizie de compatibilitate cu o consecință de securitate pe care ar trebui să o numești explicit în propriul tău model de amenințare: absența blocului nu poate fi distinsă de un atacator care l-a eliminat, pentru că atributele se află în afara MAC-ului pe care l-ar purta. Dacă controlezi ambele capete ale unui flux, tratează un bloc lipsă ca pe un eșec de politică la nivel de aplicație. Dacă accepți fișiere din lumea largă, tratează verificarea ca ceea ce este, un semnal valoros când este prezent și niciun semnal când lipsește
Parola de modificare este o convenție, nu o graniță
Registrele de lucru XLS clasice suportă un mecanism separat care este frecvent confundat cu criptarea: rezervarea la scriere, dialogul Excel „parolă de modificare”. HotXLS o expune prin SetModifyPassword, care primește parola, un flag recommend-read-only și numele utilizatorului care rezervă, și raportează starea prin IsWriteReserved. Trimiterea unei parole goale șterge rezervarea
Ce se scrie este o pereche de înregistrări WRITEPROT și FILESHARING care poartă flag-ul recommend-read-only, un hash de parolă legacy pe 16 biți și numele utilizatorului ca string Unicode BIFF8. Acel hash pe 16 biți este o sumă de control, nu un digest criptografic, iar conținutul documentului nu este criptat deloc. Oricine deschide fișierul cu orice alt instrument citește totul. Rolul real al funcționalității este coordonarea: îi spune următoarei persoane că cineva consideră acest fișier al său de editat, în aceeași categorie cu controalele la nivel de foaie acoperite în protecția foii XLSX și opțiunile allow
var
Book: IXLSWorkbook; // numărat prin interfață: nu apela Free
begin
Book := TXLSWorkbook.Create;
if Book.Open('shared-model.xls') = 1 then
begin
// Recomandă read-only, rezervat de serviciul de raportare
Book.SetModifyPassword('edit-me', True, 'Reporting Service');
if Book.IsWriteReserved then
Book.SaveAs('shared-model.xls', xlExcel97);
end;
end;
Folosește ambele straturi pentru ce este fiecare bun. Confidențialitatea reală vine din SaveAsEncrypted cu o parolă pe care nimeni din afara audienței nu o deține, ceea ce produce output-ul AES-256 descris în output XLSX protejat AES. Rezervarea la scriere se adaugă deasupra atunci când registrul de lucru este un artefact de editare partajat și vrei ca Excel să întrebe înainte ca cineva să suprascrie
Ce să verifici pe un flux de ingestie nesigur
Verificarea integrității protejează payload-ul criptat, nu containerul din jurul lui. Un fișier XLSX este o arhivă ZIP, iar structura arhivei este analizată înainte ca vreo logică de criptare să ruleze, astfel încât validarea la nivel de container aparține primului pas din lanț; modurile specifice de eșec sunt acoperite în validarea end-of-central-directory ZIP pentru XLSX nesigur. După asta, tratează un eșec de integritate și o parolă greșită ca același eveniment operațional, pentru că din partea ta sunt indistinguibile prin design, iar ambele înseamnă că fișierul nu poate fi considerat de încredere să fie ceea ce crede expeditorul
Loghează care fișiere au purtat vreun bloc dataIntegrity. Peste câteva mii de documente, această statistică îți spune ceva util despre uneltele expeditorilor tăi, și transformă o verificare per-fișier într-o observație la nivel de flotă pe care poți acționa
HotXLS citește și scrie XLS, XLSX și ODS din Delphi și C++Builder fără nicio instalare de Excel, implementând traseele de criptare Standard și Agile din [MS-OFFCRYPTO] în Pascal. API-urile de criptare, protecție și registru de lucru sunt documentate pe pagina componentei HotXLS Delphi spreadsheet