Príznak oprávnenia nie je bezpečnostný mechanizmus. Bit, ktorý hovorí „nekopírovať“, sa nachádza v tom istom slovníku /Encrypt ako samotné šifrovanie, čo mu dodáva zdanie vynútiteľnosti, ktoré v relite nemá – a v momente, keď s nimi zaobchádzate ako s jednou vecou, začne váš audit prinášať nesprávne odpovede. Jediná otázka, ktorú má zmysel pri PDF položiť, nie je to, „či je šifrované“. Je to konkrétnejšie a zložitejšie: aký algoritmus bol použitý, aká revízia bezpečnostného modulu, ktoré z dvoch hesiel bolo nastavené, ktoré bity oprávnení sú deklarované a ktorých častí súboru sa šifrovanie reálne dotýka. Súbor môže byť formálne šifrovaný a prakticky otvorený. Môže odmietnuť čítanie obsahu, no ponechať svoje metadáta ako nešifrovaný text. Môže zablokovať tlač v príznaku, ktorý však môže ľubovoľný prehliadač ignorovať. Auditovanie PDF znamená vyriešenie každého z týchto bodov samostatne a knižnica PDFlibPas od losLab pre Delphi a C++Builder ich sprístupňuje prostredníctvom plochého rozhrania API s celočíselnými popisovačmi aj cez typovanú vrstvu tried.
Čo slovník /Encrypt v skutočnosti zaznamenáva
Norma ISO 32000-1 §7.6 definuje zabezpečenie dokumentov prostredníctvom niekoľkých položiek slovníka a PDFlibPas ich kopíruje jedna k jednej v zázname TPDFEncryption. Verzia filtra V a revízia R určujú rodinu algoritmov. Vlastnosť Length nesie veľkosť kľúča. Bity oprávnení sa nachádzajú v P, overovacie reťazce pre heslo vlastníka a používateľa v O a U (s pridanými OE and UE pre verziu AES-256), sprevádza ich príznak EncryptMetadata a ďalšie tri polia určujú šifrovacie filtre aplikované na reťazce, streamy a vložené súbory.
Hodnota tohto záznamu spočíva v tom, že za vás nič neinterpretuje. Odovzdá vám surový slovník a závery nechá na vás, čo je presne to, čo audit vyžaduje. Prípad nešifrovaného obsahu vo vnútri šifrovaného PDF sa prejaví vo vlastnostiach StringFilterIdentity a StreamFilterIdentity: ak je ktorákoľvek z nich pravdivá, príslušné dáta prechádzajú cez filter Identity nedotknuté bez ohľadu na to, čo uvádza stav šifrovania dokumentu. Skener, ktorý skončí na zistení „slovník /Encrypt je prítomný“, označí takýto súbor za chránený, hoci jeho reťazce a streamy sú čitateľné ako obyčajný text. Rovnaké nuansy riadia aj metadáta. Keď je EncryptMetadata nepravdivé, balík XMP zostáva čitateľný pre akýkoľvek indexovací nástroj, zatiaľ čo obsah stránky nie je – čo je dôležité vedieť v momente, keď vaše smerovacie pravidlá závisia od poľa názvu alebo autora.
Krátky test zabezpečenia s plochým API
Pre väčšinu automatizovaných ciest odpovedajú na každodenné otázky štyri ploché volania. Metóda LoadFromFile vracia pri úspechu hodnotu 1 a po otvorení dokumentu inšpektory šifrovania podávajú správy o jeho dešifrovanom stave:
var
PDF: TPDFlib;
begin
PDF := TPDFlib.Create;
try
if PDF.LoadFromFile('contract.pdf', UserPassword) <> 1 then
raise Exception.Create('Open failed: wrong password or damaged file');
Writeln('status : ', PDF.EncryptionStatus); // decrypted / encrypted / unknown
Writeln('algorithm : ', PDF.EncryptionAlgorithm); // RC4 vs AES family
Writeln('strength : ', PDF.EncryptionStrength); // key length class
Writeln('owner pw? : ', PDF.CheckPassword(CandidatePassword));
finally
PDF.Free;
end;
end;
Metóda CheckPassword má väčší význam, než by napovedal jej jednoduchý podpis. PDF definuje dve heslá s rôznou úrovňou oprávnení. Používateľské heslo (user password) sa vyžaduje na samotné otvorenie súboru. Heslo vlastníka (owner password) udeľuje plné práva a obchádza každý bit oprávnení. Bajty na disku sú v oboch prípadoch rovnaké, ale relácia otvorená pod heslom vlastníka umožňuje operácie, ktoré relácia s používateľským heslom zakazuje. Audit, ktorý nezaznamenáva, aké poverenie bolo predložené, zaznamenáva len polovicu pravdy. Vrstva tried robí tento rozdiel dopytovateľným. Vlastnosti TPDFDocument.HasUserPassword a HasOwnerPassword informujú o tom, čo súbor vyžaduje, zatiaľ čo IsUserPassword a IsOwnerPassword hlásia, ktoré heslo reálne otvorilo aktuálnu reláciu. Tento fakt zaznamenajte do logu. Hodnoty samotných hesiel nikdy nezaznamenávajte.
Úrovne zabezpečenia, kde „AES-256“ znamená dve veci
Ploché funkcie Encrypt a EncryptFile prijímajú celočíselnú silu (Strength) s piatimi významnými hodnotami: 0 pre 40-bitové RC4, 1 pre 128-bitové RC4, 2 pre 128-bitové AES čitateľné od verzie Acrobat 7, 3 pre 256-bitové AES zavedené v programe Acrobat 9 a 4 pre 256-bitové AES vyžadované programom Acrobat X a novším.
Zaujímavé je, že hodnoty 3 a 4 sú obe označované ako AES-256, no nejde o rovnakú schému. Sila 3 sa mapuje na bezpečnostný modul (security handler) revízie 5, čo bol dočasný návrh predstavený v programe Acrobat 9, ktorý ISO nikdy neprijala. Sila 4 sa mapuje na revíziu 6, ktorej funkcia odvodzovania kľúčov bola spevnená a štandardizovaná v norme ISO 32000-2. Pre dokument, ktorý vytvárate dnes, neexistuje dôvod zvoliť verziu 3 namiesto 4. Pre audit je tento rozdiel kľúčový: pravidlo vyžadujúce „AES-256 podľa ISO 32000-2“ spĺňa iba R6 a súbor R5 deklarujúci sa ako AES-256 pri tejto podmienke zlyhá, hoci prejde jednoduchým testom sily šifrovania. Vrstva tried ich odlišuje názvom – esAES256Bit pre R5 oproti esAES256BitAcroX pre R6 – a vlastnosť EncryptionAcroX odpovedá na otázku revízie jedinou hodnotou Boolean.
Bity oprávnení a dôležité detaily o dĺžke kľúča
Funkcia EncodePermissions balí osem príznakov do celého čísla, ktoré očakávajú metódy Encrypt a EncryptFile. Základnú sadu tvorí tlač, kopírovanie, úprava a pridávanie poznámok; rozšírenú sadu vypĺňanie polí, kopírovanie pre prístupnosť, zostavovanie dokumentu a tlač vo vysokej kvalite. Dôležitým detailom, ktorý uvádza aj vlastné demo šifrovania v knižnici, je to, že rozšírená štvorica sa uplatňuje až pri sile 128 bitov a viac. Rovnaké pravidlo platí pre príznak tlače vo vysokej kvalite: ak ho vypnete na vynútenie tlače inej než v nízkom rozlíšení, 40-bitový dokument to bude ignorovať, pretože toto obmedzenie takisto vyžaduje 128-bitové alebo silnejšie šifrovanie. Ak zakódujete pravidlo „iba tlač v nízkom rozlíšení“ do 40-bitového súboru, každý prehliadač ho napriek tomu vytlačí v plnej kvalite.
Hlbšou otázkou zostáva, kto tieto bity vynucuje – a odpoveď znie, že nikto, na koho by ste sa mohli spoľahnúť. Oprávnenia sú inštrukcie pre kompatibilné prehliadače, nie kryptografické obmedzenia. Dešifrovací kľúč je úplne rovnaký, či už je kopírovanie povolené alebo zakázané, takže prísna sada oprávnení udrží na uzde iba poctivých používateľov. Prehliadač, ktorý sa rozhodne tieto bity ignorovať, nečelí žiadnej kryptografickej prekážke. Ak je vašou povinnosťou zabrániť extrakcii obsahu a nielen od nej odrádzať, súbor vyžaduje používateľské heslo a procesné riadenie na úrovni systému. Správa z auditu by mala jasne pomenovať, pod ktorý režim daný súbor spadá, namiesto interpretácie príznaku oprávnenia ako skutočného zámku.
Nastavenie pravidiel a overenie ich uplatnenia
Aplikovanie šifrovania na existujúce súbory nevyžaduje ich načítanie do objektového stromu. Metóda EncryptFile spracuje vstup na výstup v jedinom volaní a auditný cyklus opätovne otvorí výsledok na overenie toho, čo sa zapísalo na disk. Priložené demo šifrovania využíva rovnaký postup zápisu a spätného overenia:
var
PDF: TPDFlib;
R: Integer;
begin
PDF := TPDFlib.Create;
try
R := PDF.EncryptFile('in.pdf', 'out.pdf', 'owner-secret', 'user-secret', 4,
PDF.EncodePermissions(1, 0, 0, 0, // print allowed; copy/change/notes denied
0, 0, 0, 1)); // extended set: full-quality print only
if (R = 1) and (PDF.LoadFromFile('out.pdf', 'user-secret') = 1) then
begin
Writeln('algorithm = ', PDF.EncryptionAlgorithm);
Writeln('strength = ', PDF.EncryptionStrength);
Writeln('owner pw accepted: ', PDF.CheckPassword('owner-secret'));
end;
finally
PDF.Free;
end;
end;
Vývojári pracujúci na úrovni dokumentu majú k dispozícii rovnakú operáciu s typovanými sadami namiesto bitového balenia, čo uľahčuje revíziu kódu:
if not Doc.Encrypt('owner-secret', 'user-secret', esAES256BitAcroX,
[ppCanPrint], [ppCanPrintFull]) then
raise Exception.Create('Encryption failed');
Či tak alebo onak, spätné načítanie nie je len nepovinnou formalitou. Odhalí chyby nasadenia, ktoré by sa inak prejavili o niekoľko mesiacov u zákazníka: staršiu zostavu knižnice, ktorá potichu zníži požadovanú silu, nezapísanú výstupnú cestu kvôli adresáru len na čítanie alebo nesprávne poradie argumentov v celom čísle oprávnení. Všetky tri prípady prejdú lokálnym orientačným testom a zlyhajú v reálnej prevádzke. Opätovné otvorenie výstupu premení každú z týchto chýb na výnimku, ktorú uvidíte už pri spúšťaní procesu tvorby súboru. Metóda GetEncryptionFingerprint vracia kompaktnú hodnotu, ktorú môžete uložiť k záznamu o úlohe, takže neskoršie porovnanie dokáže určiť, či dva výstupy zdieľajú rovnaké nastavenie šifrovania, bez nutnosti otvárať ktorýkoľvek z nich.
Falošné pozitíva auditu, na ktoré treba myslieť v kóde
Niekoľko vzorov spoľahlivo privedie bezpečnostné skenery k nesprávnemu záveru a každý z nich vzniká zjednodušením viacdielnej otázky na odpoveď áno/nie. Najčistejším príkladom je šifrovací filter Identity. Slovník /Encrypt je prítomný, súbor sa hlási ako šifrovaný, no reťazce a streamy prechádzajú cez filter Identity bez zmeny, takže skutočný obsah je obyčajný text. Riešením je kontrola hodnôt StringFilterIdentity a StreamFilterIdentity predtým, než čokoľvek vyhlásite za chránené.
Rozdelenie metadát je jemnejšie. Hodnota EncryptMetadata sa môže rozchádzať so zvyškom dokumentu oboma smermi – ponechať šifrovaný súbor s čitateľným balíkom XMP, alebo menej často naopak. Tvrdenie „súbor je šifrovaný“ nehovorí nič o tom, či sú šifrované aj jeho metadáta, čo je dôležité v momente, keď indexovací nástroj alebo smerovacie pravidlo načítava názov dokumentu. Vložené súbory pridávajú tretiu os: PDF umožňuje vyhradený šifrovací filter len pre prílohy, takže prílohy môžu byť jedinou šifrovanou časťou inak otvoreného dokumentu, prípadne jedinou nešifrovanou časťou šifrovaného dokumentu. Zaznamenajte tri priradenia filtrov ako samostatné polia pre reťazce, streamy a vložené súbory a tieto úskalia vás neprekvapia. Uložte jedinú hodnotu Boolean a chybná interpretácia je len otázkou času.
Odstránenie šifrovania a jeho voľba pre nové súbory
Audit často končí rozhodnutím odstrániť ochranu a technické riešenie tu nepredstavuje prekážku. Metóda DecryptFile(InputFileName, OutputFileName, Password) zapíše dešifrovanú kópiu bez nutnosti úplného načítania dokumentu a metóda Decrypt na načítanom dokumente urobí to isté v pamäti, ak je už súbor otvorený. Obe vyžadujú platné heslo; ani jedna neobchádza kryptografiu. Skutočnou bariérou sú pravidlá a nie kód – nastavte pravidlá prijímania tak, aby jasne definovali, kedy je odstránenie povolené, a zaznamenajte triedu hesla, ktorá ho autorizovala, pretože samotný technický krok po sebe nezanecháva žiadnu stopu.
Vo voľba pre nový výstup je užšia, než naznačuje päť hodnôt sily šifrovania. Používajte silu 4, AES-256 revízie 6, pokiaľ nemusíte otvárať súbory v prehliadačoch starších ako Acrobat X. Sila 2, AES-128, je pragmatickým minimom pre staršie verzie prehliadačov, ktoré sa nedajú aktualizovať. Možnosti RC4 na hodnotách 0 a 1 sú určené len na čítanie a audit historických archívov, nie na vytváranie nového obsahu; ich použitie v návrhoch z roku 2026 naznačuje, že požiadavky zadania sú neaktuálne.
Stav šifrovania priamo ovplyvňuje rozhodovanie o podpisovaní, keďže vývojové prostredie overujúce a podpisujúce dokumenty vyžaduje rovnakú disciplínu spätného načítania, na akú sa spolieha tento audit. Táto téma je rozobraná v článku o prostredí pre kontrolu zhody a podpisovanie. Pri hromadnom použití EncryptFile na tisícoch veľkých dokumentov vám sprievodca priamym prístupom k veľkým PDF ukáže, ako udržať stabilnú spotrebu pamäte. Kompletná referenčná príručka pre API šifrovania sa nachádza na produktovej stránke PDFlibPas.