Excel vystavuje dvě věci, kterým se říká „heslo", a jen jedna z nich je šifrování. Heslo pro otevření je klíčem ke skutečné šifře: bez něj se soubor vůbec nedá přečíst. Hesla pro ochranu listu a sešitu nedělají nic podobného. Nastaví příznak, který se spolupracující editor zavazuje respektovat, a sešit, který nese jen tento příznak, je obyčejný čitelný zip s daty ležícími v čistém textu. Vyberete-li to špatné, doručíte mzdový přehled, který v Excelu vypadá zamčeně a v jakémkoli textovém editoru se čte úplně normálně
Důkaz zabere deset vteřin. Přejmenujte chráněný .xlsx na .zip, otevřete ho v libovolném archivačním nástroji a podívejte se na xl/worksheets/sheet1.xml. Pokud jsou tam hodnoty buněk v čistém UTF-8, soubor není šifrovaný, ať Excel při pokusu upravit buňku vyvolá sebevíc dotazů na heslo. Tato mezera přežívá roky v týmech, které předpokládají, že ochrana listu je důvěrnost, a obvykle vyplave na povrch v den, kdy bezpečnostní kontrola provede přesně tohle přejmenování
HotXLS je nativní knihovna pro Delphi a C++Builder pro práci s tabulkovými procesory a tyto dvě funkce drží na opačných stranách této hranice. Ochrana listu a sešitu jsou editační omezení podložená záměrně slabým starším hashem. SaveAsEncrypted vytvoří balíček šifrovaný AES, který neotevře nic kromě hesla. Následující sekce popisují, co toto volání zapisuje, asymetrii, se kterou musíte v architektuře počítat (HotXLS šifrované soubory zapisuje, ale neumí je zpět přečíst), a v čem se liší starší cesta XLS
Proč ochrana listu není šifrování
Metody Protect na listech a ProtectWorkbook na sešitu ukládají 4místný hexadecimální hash hesla. To je starší algoritmus, který OOXML i BIFF zdědily z Excelu devadesátých let, a dokumentace formátu nikdy netvrdí, že dělá víc, než že zastavuje náhodné úpravy. Balíček zůstává obyčejným čitelným zipem: data buněk, vzorce i sdílené řetězce, vše v čistém XML. Výchozí nastavení to ještě zhoršuje, ne zlepšuje. Každá buňka začíná s Locked=True, takže zavolání Protect bez předchozího odemknutí vstupního rozsahu zamrazí celý list proti editaci, zatímco každá hodnota zůstává na očích
Nic z toho ale nedělá ochranu zbytečnou. Nasměrování uživatelů do editovatelných rozsahů a stabilizace rozvržení pro tisk jsou reálné úkoly, popsané v našem článku o ochraně listu a nastavení stránky. Jenže to jsou úkoly týkající se použitelnosti. Ve chvíli, kdy je požadavkem důvěrnost, jediné API, které na ni odpovídá, je SaveAsEncrypted
Co SaveAsEncrypted skutečně zapisuje
Implementace se řídí ECMA-376 Standard Encryption, specifikovaným v [MS-OFFCRYPTO] sekci 2.3.4. Heslo projde 50 000 iteracemi SHA-1, aby se z něj odvodil klíč AES-128. Ověřovací blok, zašifrovaný pomocí AES-128 v režimu ECB, umožňuje konzumentovi potvrdit heslo dřív, než cokoli dešifruje, a celý balíček sešitu je pak zašifrován pomocí AES-128 v režimu CBC. Na disk nedopadne žádný zip. Je to soubor typu OLE compound file obsahující streamy EncryptionInfo, EncryptedPackage a DataSpaces, bez adresáře xl/, který by mohl archivační nástroj vypsat, a proto test s přejmenováním teď nenajde nic čitelného. Excel 2007 a novější ho otevře jen s heslem, a i aktuální LibreOffice umí Standard Encryption přečíst
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;
Zacházejte s proměnnou hesla se stejnou péčí jako s connection stringem. Získejte ho z trezoru nebo služby pro generovaná tajemství až na poslední chvíli, nikdy ho nelogujte a nikdy ho nezapisujte do samotného sešitu. Kontrola návratového kódu není zbytná ceremonie navíc. Šifrované uložení, které selže uprostřed, musí doručení přerušit, protože jediný náhradní plán, který volající kód nabídne, je nešifrovaná kopie, a přesně té kopii má tato funkce zabránit
Existuje také strojově ověřitelný akceptační test, který stojí téměř nic: zavolejte CanReadEncrypted na soubor, který jste právě zapsali. Vrátí true jen tehdy, když je výstup skutečně šifrovacím kontejnerem, takže jeho ověření po každém šifrovaném uložení zachytí nejdůležitější regresi, kód, který se potichu vrátil k obyčejnému SaveAs, přesně ve chvíli, kdy se to stane, ne o týdny později v zákazníkově schránce. Poslední slovo pořád patří ručnímu otevření v Excelu se skutečným heslem během testování před vydáním
Záměrně jen pro zápis: ošetření EXlsxEncryptionNotImplemented
Tady je asymetrie, která by měla utvářet architekturu vašeho pipeline: HotXLS při ukládání šifruje, ale při otevírání nedešifruje. OpenEncrypted vyvolá EXlsxEncryptionNotImplemented, když je namířeno na skutečně šifrovaný balíček; u obyčejného sešitu prostě propadne do normálního Open. Doprovodná sonda CanReadEncrypted levně detekuje šifrovací kontejner OLE, takže vstupní kód může takové soubory směrovat, aniž by výjimku vůbec vyvolal:
var
Book: TXLSXWorkbook;
begin
Book := TXLSXWorkbook.Create;
try
if Book.CanReadEncrypted(FileName) then
begin
// Šifrovaný kontejner: HotXLS ho nedokáže dešifrovat.
Writeln(FileName + ': needs manual decryption in Excel first');
Exit;
end;
try
Book.OpenEncrypted(FileName, ''); // nešifrované soubory propadnou do 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;
Tato asymetrie má jeden jasný architektonický výklad: šifrujte až na doručovací hraně, jako poslední krok. Nešifrovaný master držte uvnitř své důvěryhodné hranice, v databázi, dokumentovém úložišti nebo sdílení s řízeným přístupem, a šifrovanou kopii vyprodukujte jako poslední krok předtím, než soubor opustí systém. Pipeline, který archivuje jen šifrovaný výstup, se sám vyzamkl ze svých vlastních dat, protože žádná pozdější fáze téhož systému ty soubory nedokáže znovu otevřít. Když navazující proces HotXLS workbook znovu potřebuje, předejte mu nešifrovaný master, nikdy doručovací artefakt
AES-128 Standard Encryption a hranice compliance AES-256
Šifrování souborů Office přichází ve dvou generacích. Standard Encryption, ta, kterou zapisuje HotXLS, používá AES-128 s odvozením klíče přes SHA-1. Agile Encryption přišlo později a přechází na AES-256 se SHA-512 a jiným, XML popsaným kontejnerem klíčů. Obě se v Excelu otevřou transparentně, a AES-128 je stále výpočetně dostatečně silné pro ochranu souboru na cestě k zákazníkovi
Rozdíl přestává být akademický v den, kdy bezpečnostní dotazník požaduje „šifrování souborů v klidu AES-256". Standard Encryption tuto hranici nesplňuje, bez ohledu na to, jak silné je heslo, a žádný parametr SaveAsEncrypted algoritmus, který produkuje, nezmění. Uveďte tedy ve své bezpečnostní dokumentaci profil přesně: AES-128, ECMA-376 Standard Encryption, odvození klíče SHA-1 s 50 000 iteracemi. Tvrzení, které přežije revizi, má větší cenu než optimistické tvrzení, které se zhroutí při auditu
Starší cesta XLS: RC4 ven, RC4 a XOR zase zpátky
Fasáda BIFF má opačný tvar. Její šifrování je starší a slabší, ale round-trip je úplný: co zapíše, dokáže i zpátky přečíst. Nastavení EncryptionPassword před SaveAs vyprodukuje přes mechanismus BIFF FilePass soubor .xls šifrovaný RC4, a Open s parametrem hesla přečte všechna tři starší schémata: RC4, RC4 CryptoAPI a prastarou obfuskaci XOR:
var
Writer, Reader: IXLSWorkbook; // reference přes rozhraní: bez ručního 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); // Položky jsou indexovány od 1
end;
RC4 je zastaralá kryptografie a nikdy by neměla chránit data, na kterých dnes záleží; jedinou zbývající hodnotou je interoperabilita se systémy, které si stále vyměňují .xls. Čtecí strana si ale svou existenci zaslouží v migrační práci. Heslem chráněný starší soubor se otevře pomocí Open(FileName, Password), přemostí se do modelu OOXML a znovu zabezpečí cestou AES, jednosměrný upgrade, který proběhne bez Excelu kdekoli ve smyčce. Pro hromadné šifrované doručování platí poznámky o propustnosti na straně ukládání z našeho článku o streamovaném zápisu pro dávkové úlohy na serveru na fázi tvorby obsahu, která probíhá před šifrováním
Šifrování a ochrana nejsou soupeři
Ještě jeden bod stojí za ujasnění, protože vyvstane ve chvíli, kdy si někdo varování na začátku této stránky vyloží jako „ochrana je k ničemu". Není. Šifrování a ochrana odpovídají na jiné otázky a čistě se skládají na sebe. Šifrování rozhoduje, kdo může soubor otevřít; ochrana rozhoduje, co smí změnit čtenář, který už uvnitř je. Doručení mzdového přehledu může rozumně dělat obojí: zašifrovat balíček, aby ho viděl jen držitel hesla, a pak zamknout buňky se vzorci, aby příjemce mohl filtrovat a řadit, ale ne potichu přepisovat výpočty. Chybou nikdy není přidat ochranu. Chybou je nechat její přítomnost zastupovat šifrování ve chvíli, kdy byl požadavkem důvěrnost
Strana péče o hesla nemá žádnou záchrannou síť, a je to tak záměrně. Odvození klíče s 50 000 iteracemi existuje proto, aby bylo hádání drahé, a nic uvnitř souboru tajemství neuchovává v úschově. Ztracené heslo znamená ztracená data. Generujte, doručujte a ukládejte tato hesla se stejnou disciplínou, jakou uplatňujete u databázových přihlašovacích údajů, a šifrování dodrží svou část dohody
Skutečné šifrování souboru je v HotXLS jedno volání. Disciplína žije ve všem kolem tohoto volání: péče o heslo, hranice jen pro zápis, která brání HotXLS znovu otevřít svůj vlastní výstup, a tvrzení o algoritmu, které dokážete obhájit při auditu. SaveAsEncrypted a starší round-trip jsou součástí HotXLS Delphi Component, běžícího nativně v procesech Delphi a C++Builder bez jakékoli automatizace Excelu kdekoli na cestě