Excel expune două elemente numite ambele „parolă”, însă doar unul dintre ele reprezintă criptarea propriu-zisă. Parola de deschidere activează un cifru real: fără ea, fișierul nu poate fi citit deloc. Parolele de protecție ale foilor și registrului de lucru nu realizează o astfel de operațiune; ele configurează doar un marcaj pe care un editor compatibil acceptă să îl respecte, iar un registru de lucru care conține doar acest marcaj este o arhivă zip simplă și lizibilă, datele fiind stocate ca text clar. Dacă alegeți opțiunea greșită, puteți livra un document de salarii care pare blocat în Excel, dar care poate fi citit cu orice editor de text
Redenumiți un fișier protejat .xlsx în .zip, deschideți-l în orice instrument de arhivare și verificați xl/worksheets/sheet1.xml. Dacă valorile celulelor sunt vizibile în format UTF-8 clar, fișierul nu este criptat, indiferent de solicitările de introducere a parolei pe care Excel le afișează la încercarea de editare a unei celule. Această problemă persistă ani de zile în cadrul echipelor care confundă protecția foilor cu confidențialitatea și, de regulă, iese la iveală în ziua în care o analiză de securitate execută exact această redenumire
HotXLS este o bibliotecă nativă de foi de calcul pentru Delphi și C++Builder și păstrează cele două caracteristici pe părți diferite ale acestei granițe. Protecția foilor și a registrului reprezintă restricții de editare bazate pe un hash vechi și slab din proiectare. Metoda SaveAsEncrypted generează un pachet criptat AES pe care doar parola corectă îl poate deschide. Secțiunile de mai jos descriu ce scrie acest apel, asimetria pe care trebuie să o luați în considerare în arhitectura dvs. (HotXLS scrie fișiere criptate, dar nu le poate citi înapoi) și modul în care diferă calea veche XLS
De ce protecția foii nu înseamnă criptare
Metodele Protect de pe foi și ProtectWorkbook de pe registru stochează un hash de 4 cifre hexazecimale al parolei. Acesta este algoritmul vechi pe care OOXML și BIFF l-au moștenit din versiunile Excel din anii '90, iar documentația formatului nu pretinde că oferă mai mult decât prevenirea editărilor accidentale. Pachetul rămâne o arhivă zip obișnuită și lizibilă: datele celulelor, formulele și șirurile partajate sunt stocate ca XML în text clar. Setarea implicită complică situația: fiecare celulă pornește cu starea Locked=True, așa că apelarea Protect fără a debloca în prealabil un interval de introducere a datelor blochează întreaga foaie la editare, lăsând în același timp toate valorile la vedere
Nimic din toate acestea nu înseamnă că protecția este inutilă. Direcționarea utilizatorilor către intervale editabile și stabilizarea structurii pentru imprimare sunt sarcini reale, prezentate în articolul nostru despre protecția foilor de calcul și configurarea paginii. Însă acestea sunt activități care țin de utilizare. În momentul în care cerința vizează confidențialitatea datelor, singura interfață API care răspunde acestei nevoi este SaveAsEncrypted
Ce scrie în realitate SaveAsEncrypted
Implementarea respectă specificațiile ECMA-376 Standard Encryption, descrise în [MS-OFFCRYPTO] secțiunea 2.3.4. Parola trece prin 50.000 de iterații SHA-1 pentru a genera o cheie AES-128. Un bloc verificator, criptat cu AES-128 în modul ECB, permite unui cititor să confirme parola înainte de a decripta conținutul propriu-zis, iar întregul pachet al registrului este apoi criptat cu AES-128 în modul CBC. Ceea ce se salvează pe disc nu mai este o arhivă zip, ci un fișier compus OLE (CFB) care conține fluxurile EncryptionInfo, EncryptedPackage și DataSpaces, fără niciun director xl/ pe care un instrument de arhivare să îl poată lista, motiv pentru care testul de redenumire nu mai afișează date lizibile. Excel 2007 și versiunile ulterioare îl deschid doar pe baza parolei, iar versiunile actuale de LibreOffice pot citi de asemenea Standard Encryption
var
Book: TXLSXWorkbook;
Sheet: TXLSXWorksheet;
rc: Integer;
begin
Book := TXLSXWorkbook.Create;
try
Sheet := Book.Sheets.Add('Payroll');
Sheet.Cells[1, 1].Value := 'Employee';
Sheet.Cells[1, 2].Value := 'Net pay';
Sheet.Cells[2, 1].Value := 'A. Garcia';
Sheet.Cells[2, 2].Value := 4815.16;
rc := Book.SaveAsEncrypted('payroll-2026-06.xlsx', PasswordFromVault);
if rc <> 1 then
raise Exception.CreateFmt('Encrypted save failed (rc=%d)', [rc]);
finally
Book.Free;
end;
end;
Tratați variabila parolei cu aceeași atenție ca pe un șir de conexiune. Preluați-o dintr-un seif (vault) sau dintr-un serviciu de generare a cheilor secrete în ultimul moment, nu o înregistrați în jurnalul de logare și nu o scrieți niciodată în registrul de lucru propriu-zis. Verificarea codului returnat nu este o simplă formalitate. O salvare criptată care eșuează pe parcurs trebuie să oprească livrarea, deoarece singura alternativă pe care o poate oferi codul apelant este o copie necriptată, iar acea copie reprezintă exact incidentul pe care această caracteristică încearcă să îl prevină
Există de asemenea un test de acceptare ce poate fi rulat automat cu costuri minime: apelați funcția CanReadEncrypted pentru fișierul proaspăt scris. Aceasta returnează true doar atunci când rezultatul este într-adevăr un container de criptare, astfel încât utilizarea ei după fiecare salvare criptată depistează regresia cea mai importantă — o cale de cod care a recurs în mod silențios la o salvare simplă SaveAs — chiar în momentul în care se produce, nu săptămâni mai târziu în adresa de primire a clientului. Confirmarea finală este oferită tot de o deschidere manuală în Excel cu parola reală în timpul testelor de lansare
Write-only prin proiectare: gestionarea EXlsxEncryptionNotImplemented
Iată asimetria care ar trebui să definească arhitectura liniei dvs. de procesare: HotXLS criptează la salvare, dar nu decriptează la deschidere. Metoda OpenEncrypted generează eroarea EXlsxEncryptionNotImplemented când este direcționată către un pachet criptat; în cazul unui registru simplu, aceasta recurge normal la calea Open. Funcția asociată CanReadEncrypted detectează rapid containerul de criptare OLE, astfel încât codul de import poate direcționa aceste fișiere fără a declanșa excepția:
var
Book: TXLSXWorkbook;
begin
Book := TXLSXWorkbook.Create;
try
if Book.CanReadEncrypted(FileName) then
begin
// Encrypted container: HotXLS cannot decrypt it.
Writeln(FileName + ': needs manual decryption in Excel first');
Exit;
end;
try
Book.OpenEncrypted(FileName, ''); // plain files fall through to Open
Writeln(FileName + ': opened, ' + IntToStr(Book.Sheets.Count) + ' sheet(s)');
except
on EXlsxEncryptionNotImplemented do
Writeln(FileName + ': encrypted - routed to manual queue');
end;
finally
Book.Free;
end;
end;
Această asimetrie impune o regulă clară de arhitectură: criptează la final, la nivelul de livrare. Păstrați documentul original în format text clar în zona dvs. de siguranță — într-o bază de date, într-un depozit de documente sau într-o partajare cu acces controlat — și generați copia criptată ca ultim pas înainte ca fișierul să părăsească sistemul. O linie de procesare care arhivează exclusiv rezultatele criptate își blochează accesul la propriile date, deoarece nicio etapă ulterioară a aceluiași sistem nu va putea redeschide acele fișiere. Când un proces HotXLS din aval are nevoie din nou de registrul de lucru, furnizați-i originalul în format text clar, niciodată documentul de livrare
AES-128 Standard Encryption și conformitatea AES-256
Criptarea fișierelor Office este de două tipuri. Standard Encryption, cel pe care îl scrie HotXLS, utilizează AES-128 cu derivare de cheie SHA-1. Criptarea Agile a apărut ulterior și trece la AES-256 cu SHA-512 și un alt container de cheie definit prin XML. Ambele tipuri sunt deschise transparent în Excel, iar AES-128 este în continuare o metodă sigură din punct de vedere al calculului pentru protejarea unui fișier în tranzit către un client
Diferența încetează să mai fie pur teoretică în ziua în care un chestionar de securitate solicită „criptare AES-256 pentru fișierele stocate”. Standard Encryption nu îndeplinește această cerință, indiferent de complexitatea parolei, și niciun parametru al metodei SaveAsEncrypted nu modifică algoritmul pe care îl generează. Așadar, precizați exact profilul în documentația dvs. de securitate: AES-128, ECMA-376 Standard Encryption, derivare de cheie SHA-1 cu 50.000 de iterații. O declarație corectă este mult mai valoroasă decât una optimistă care eșuează la un audit
Calea veche XLS: RC4 la scriere, RC4 și XOR la citire
Structura BIFF funcționează invers. Criptarea sa este mai veche și mai slabă, dar permite un proces complet: ceea ce scrie poate citi înapoi. Configurarea EncryptionPassword înainte de SaveAs generează un fișier .xls criptat RC4 prin mecanismul BIFF FilePass, iar metoda Open cu un parametru de parolă poate citi toate cele trei scheme vechi: RC4, RC4 CryptoAPI și vechea ofuscare XOR:
var
Writer, Reader: IXLSWorkbook; // interface refs: no manual Free
begin
Writer := TXLSWorkbook.Create;
Writer.Sheets.Add.Cells.Item[1, 1].Value := 'Confidential';
Writer.EncryptionPassword := 'S3cret!';
Writer.SaveAs('confidential.xls');
Reader := TXLSWorkbook.Create;
if Reader.Open('confidential.xls', 'S3cret!') > 0 then
Writeln(Reader.Sheets[1].Cells.Item[1, 1].Value); // Entries are 1-based
end;
Mecanismul RC4 este o metodă criptografică învechită și nu ar trebui să mai protejeze date importante; singura sa utilitate rămâne interoperabilitatea cu sisteme care folosesc în continuare formatul .xls. Partea de citire este însă utilă în activitățile de migrare. Un fișier vechi protejat prin parolă se deschide cu Open(FileName, Password), este transferat în modelul OOXML și este securizat prin calea AES, o actualizare într-un singur sens care rulează fără a necesita Excel în proces. Pentru volume mari de livrări criptate, notele privind viteza de scriere din articolul nostru despre scrierea în flux pentru sarcini de server se aplică etapei de construire a conținutului care are loc înainte de criptare
Criptarea și protecția nu se exclud reciproc
Un alt aspect important, util atunci când cineva consideră că „protecția este inutilă”. Nu este așa. Criptarea și protecția răspund la întrebări diferite și pot fi utilizate împreună. Criptarea stabilește cine poate deschide fișierul, în timp ce protecția decide ce poate modifica un cititor care are deja acces. O livrare de date de salarii poate folosi ambele metode: criptează pachetul astfel încât doar posesorul parolei să îl vadă, poi blochează celulele cu formule astfel încât destinatarul să poată filtra și sorta, dar să nu poată rescrie calculele. Greșeala nu constă în utilizarea protecției, ci în considerarea prezenței acesteia ca o alternativă la criptare atunci când cerința vizează confidențialitatea datelor
Administrarea parolelor nu oferă o plasă de siguranță, iar acest lucru este prevăzut prin proiectare. Derivarea cheii cu 50.000 de iterații este concepută pentru a îngreuna ghicirea, iar fișierul nu stochează cheia de rezervă. O parolă pierdută înseamnă pierderea datelor. Generați, livrați și stocați aceste parole cu aceeași rigoare pe care o aplicați acreditărilor pentru bazele de date, iar criptarea își va îndeplini rolul
Criptarea reală a unui fișier reprezintă un singur apel în HotXLS. Rigoarea se reflectă în tot ceea ce înconjoară apelul: administrarea parolei, limita write-only care împiedică HotXLS să își redeschidă propriul rezultat și o utilizare a algoritmului pe care o puteți susține la un audit. Metoda SaveAsEncrypted și procesul complet pentru fișiere vechi sunt livrate cu HotXLS Component, rulând nativ în procese Delphi și C++Builder fără a necesita automatizarea Excel în calea de rulare