Excel izlaže dvije stvari koje se nazivaju 'lozinka', a samo je jedna od njih šifriranje. Lozinka za otvaranje aktivira pravi šifrant: bez nje se datoteka uopće ne može pročitati. Lozinke za zaštitu radnog lista i radne knjige ne čine ništa slično. One postavljaju zastavicu koju se urednik koji surađuje slaže poštovati, a radna knjiga koja nosi samo tu zastavicu obična je čitljiva zip arhiva s podacima u čistom tekstu. Odaberite pogrešnu i poslat ćete podatke o plaćama koji izgledaju zaključano u Excelu, a mogu se pročitati u bilo kojem uređivaču teksta.
Dokaz traje deset sekundi. Preimenujte zaštićenu .xlsx datoteku u .zip, otvorite je u bilo kojem alatu za arhiviranje i pogledajte xl/worksheets/sheet1.xml. Ako su vrijednosti ćelija tamo u običnom UTF-8 formatu, datoteka nije šifrirana, bez obzira na to koliko upita za lozinku Excel postavlja kada netko pokuša urediti ćeliju. Taj propust godinama opstaje u timovima koji pretpostavljaju da je zaštita lista isto što i povjerljivost, a obično ispliva na površinu onog dana kada sigurnosna provjera pokrene upravo ovo preimenovanje.
HotXLS isporučen je kao izvorna knjižnica za tablične proračune za Delphi i C++Builder, i drži ove dvije značajke na suprotnim stranama te linije. Zaštita radnog lista i radne knjige su ograničenja uređivanja podržana namjerno slabim naslijeđenim hashom. SaveAsEncrypted proizvodi paket šifriran AES-om koji se ne može otvoriti bez lozinke. Sljedeći odjeljci pokrivaju što taj poziv piše, asimetriju oko koje morate dizajnirati sustav (HotXLS piše šifrirane datoteke, ali ih ne može čitati natrag) i kako se starija XLS staza razlikuje.
Zašto zaštita lista nije šifriranje
Metode Protect na listovima i ProtectWorkbook na radnoj knjizi pohranjuju 4-znamenkasti heksadecimalni hash lozinke. To je naslijeđeni algoritam koji su i OOXML i BIFF naslijedili iz Excela iz 1990-ih, a dokumentacija formata nikada ne tvrdi da čini više od zaustavljanja slučajnih uređivanja. Paket ostaje obična čitljiva zip arhiva: podaci ćelija, formule i zajednički nizovi znakova nalaze se u čistom tekstu XML-a. Zadana postavka to čini još gorim. Svaka ćelija počinje s Locked=True, pa pozivanje Protect bez prethodnog otključavanja ulaznog raspona zaključava cijeli list za uređivanje, dok svaku vrijednost ostavlja na vidjelu.
Ništa od toga ne čini zaštitu beskorisnom. Usmjeravanje korisnika u raspon koji se može uređivati i stabilizacija izgleda za ispis stvarni su zadaci, obrađeni u našem članku o zaštiti radnih listova i postavljanju stranice. Ali to su zadaci upotrebljivosti. U trenutku kada je zahtjev povjerljivost, jedini API koji na to odgovara jest SaveAsEncrypted.
Što SaveAsEncrypted zapravo piše
Implementacija prati standardno šifriranje ECMA-376, specificirano u [MS-OFFCRYPTO] odjeljku 2.3.4. Lozinka prolazi kroz 50.000 iteracija SHA-1 kako bi se izvedao AES-128 ključ. Blok verifikatora, šifriran pomoću AES-128 u ECB načinu rada, omogućuje klijentu da potvrdi lozinku prije nego što bilo što dešifrira, a cijeli paket radne knjige se zatim šifrira pomoću AES-128 u CBC načinu rada. Ono što slijeće na disk uopće nije zip arhiva. To je OLE složena datoteka (compound file) koja sadrži tokove EncryptionInfo, EncryptedPackage i DataSpaces, bez xl/ direktorija koji bi alat za arhiviranje mogao izlistati, zbog čega test preimenovanja sada ne prikazuje ništa čitljivo. Excel 2007 i noviji otvaraju ga samo s lozinkom, a i trenutni LibreOffice čita standardno šifriranje.
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;
Tretirajte varijablu lozinke s istom pažnjom kao i niz za povezivanje s bazom podataka (connection string). Dohvatite je iz trezora (vault) ili servisa za generiranje tajni u posljednjem trenutku, nikada je nemojte bilježiti u dnevnik i nikada je ne zapisujte u samu radnu knjigu. Provjera povratnog koda nije neobavezna ceremonija. Šifrirano spremanje koje ne uspije na pola puta mora prekinuti isporuku, jer jedina alternativa koju pozivni kod može ponuditi jest nešifrirana kopija, a ta je kopija upravo onaj incident koji ova značajka želi spriječiti.
Postoji i strojno provjerljiv test prihvaćanja koji ne košta gotovo ništa: pozovite CanReadEncrypted na datoteci koju ste upravo zapisali. Vraća true samo kada je izlaz stvarno spremnik šifriranja, pa provjera toga nakon svakog šifriranog spremanja hvata najvažniju regresiju (stazu koda koja se potiho vratila na obično SaveAs) u trenutku kada se to dogodi, a ne tjednima kasnije u klijentovoj pristigloj pošti. Zadnja riječ ipak pripada ručnom otvaranju u Excelu sa stvarnom lozinkom tijekom testiranja izdanja.
Samo za pisanje po dizajnu: rukovanje s EXlsxEncryptionNotImplemented
Evo asimetrije koja bi trebala oblikovati arhitekturu vašeg cjevovoda: HotXLS šifrira pri spremanju, ali ne dešifrira pri otvaranju. OpenEncrypted podiže iznimku EXlsxEncryptionNotImplemented kada se usmjeri na stvarni šifrirani paket; na običnoj radnoj knjizi jednostavno prelazi na normalan Open. Prateća sonda CanReadEncrypted jeftino otkriva OLE spremnik šifriranja, tako da ulazni kod može usmjeriti takve datoteke bez izazivanja iznimke:
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;
Ta asimetrija ima jedno jasno arhitektonsko čitanje: šifrirajte na samom rubu isporuke, na kraju. Držite čisti tekst (plaintext) unutar svoje granice povjerenja, u bazi podataka, spremištu dokumenata ili dijeljenom resursu s kontrolom pristupa, a šifriranu kopiju proizvedite kao posljednji korak prije nego što datoteka napusti sustav. Cjevovod koji arhivira samo šifrirani izlaz zaključao je sam sebe iz vlastitih podataka, jer nijedna kasnija faza istog sustava ne može ponovno otvoriti te datoteke. Kada nizvodni proces HotXLS ponovno zatreba radnu knjigu, predajte mu izvornik u čistom tekstu, a nikada isporučeni artefakt.
AES-128 Standard Encryption i usklađenost s AES-256
Šifriranje Office datoteka dolazi u dvije generacije. Standardno šifriranje, ono koje HotXLS piše, koristi AES-128 s izvedbom ključa SHA-1. Agile šifriranje stiglo je kasnije i prelazi na AES-256 s SHA-512 i drugačijim spremnikom ključeva opisanim XML-om. Oba se transparentno otvaraju u Excelu, a AES-128 je i dalje računalno siguran za zaštitu datoteke u tranzitu do kupca.
Razlika prestaje biti akademska onog dana kada sigurnosni upitnik zatraži 'AES-256 šifriranje datoteka u mirovanju (at rest)'. Standardno šifriranje ne zadovoljava tu granicu, bez obzira na to koliko je lozinka jaka, a nijedan parametar SaveAsEncrypted ne mijenja algoritam koji emitira. Stoga precizno navedite profil u svojoj sigurnosnoj dokumentaciji: AES-128, standardno šifriranje ECMA-376, izvedba ključa SHA-1 s 50.000 iteracija. Tvrdnja koja preživi pregled vrijedi više od optimistične koja se uruši pod revizijom.
Naslijeđena XLS ruta: RC4 van, RC4 i XOR natrag unutra
Sučelje BIFF ima suprotan oblik. Njegovo je šifriranje starije i slabije, ali je cijeli krug potpun: ono što zapiše, može i pročitati natrag. Postavljanje EncryptionPassword prije SaveAs proizvodi RC4-šifrirani .xls kroz mehanizam BIFF FilePass, a Open s parametrom lozinke čita sve tri naslijeđene sheme, RC4, RC4 CryptoAPI i prastaru XOR obfuskaciju:
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;
RC4 je zastarjela kriptografija i nikada ne bi trebala štititi podatke koji su danas važni; njezina jedina preostala vrijednost je interoperabilnost sa sustavima koji još uvijek razmjenjuju .xls. Strana čitanja, međutim, opravdava svoje postojanje u migracijskom radu. Labavo zaštićena naslijeđena datoteka otvara se pomoću Open(FileName, Password), premošćuje se u OOXML model i ponovno osigurava kroz AES stazu, što predstavlja jednosmjernu nadogradnju koja radi bez Excela bilo gdje u petlji. Za šifrirane isporuke velikog volumena, napomene o propusnosti na strani spremanja iz našeg članka o strujnom pisanju za poslužiteljske skupne poslove primjenjuju se na fazu izgradnje sadržaja koja se događa prije šifriranja.
Šifriranje i zaštita nisu suparnici
Još jednu točku vrijedi razjasniti jer se javlja u trenutku kada netko pročita upozorenje na vrhu ove stranice kao 'zaštita je bezvrijedna'. Nije. Šifriranje i zaštita odgovaraju na različita pitanja i čisto se nadograđuju. Šifriranje odlučuje tko može otvoriti datoteku; zaštita odlučuje što čitatelj koji je već unutra smije promijeniti. Isporuka platnih lista može razumno činiti oboje: šifrirati paket tako da ga vidi samo imatelj lozinke, a zatim zaključati ćelije s formulama kako bi primatelj mogao filtrirati i sortirati, ali ne i potiho prepisivati izračune. Pogreška nikada nije u dodavanju zaštite. Pogreška je dopustiti da njezina prisutnost zamijeni šifriranje kada je zahtjev bio povjerljivost.
Strana čuvanja lozinki nema sigurnosnu mrežu, i to je namjerno. Izvođenje ključa od 50.000 iteracija postoji kako bi pogađanje bilo skupo, a ništa unutar datoteke ne pohranjuje tajnu kod treće strane (escrow). Izgubljena lozinka je izgubljen podatak. Generirajte, isporučujte i pohranjujte ove lozinke s istom disciplinom koju primjenjujete na vjerodajnice baze podataka, i šifriranje će odraditi svoj dio posla.
Pravo šifriranje datoteka je jedan poziv u HotXLS-u. Disciplina živi u svemu oko tog poziva: čuvanju lozinke, granici samo za pisanje koja sprječava HotXLS da ponovno otvori vlastiti izlaz i tvrdnji o algoritmu koju možete braniti u reviziji. SaveAsEncrypted i naslijeđeni kružni tok isporučuju se s komponentom HotXLS, a izvode se izvorno u Delphi i C++Builder procesima bez ikakve automatizacije Excela u stazi.