Odborný článok

Klasifikácia zmien v PDF po podpise dokumentu

Podpis nad PDF nezakazuje neskoršie zmeny. Fixuje bajtový rozsah a inkrementálna aktualizácia pripája nové bajty za neho, takže podpis zostáva matematicky platný, kým dokument získava nový obsah. To, či je ten obsah prijateľný, je otázka politiky a DocMDP je miesto, kde autor politiku vyjadruje: žiadne zmeny vôbec, len vyplňanie formulárov a podpisovanie, alebo to plus anotácie. Vynútiť ju znamená klasifikovať, čo sa skutočne zmenilo, a to robí AnalyzeModifications. Namierte ju na skoršiu revíziu, potom si prečítajte GetModificationLevel pre celkový verdikt a prístupové metódy pre jednotlivé nálezy vrátia úroveň, číslo objektu a popis každého rozdielu

S týmto na mieste sa vynútenie DocMDP zredukuje na porovnanie: je vypočítaná úroveň na úrovni alebo pod úrovňou, ktorú politika povoľuje

Diagram rebríka úrovní úprav PDFlibPas od mlNone po mlUnclassified ukazujúci vynútenie politiky DocMDP ako jedno porovnanie v Delphi
Rebrík TPLModificationLevel beží od mlNone po mlUnclassified a vynútenie DocMDP sa redukuje na porovnanie vypočítanej úrovne s politikou

Prečo sa od podpísaného PDF očakáva zmena

Tri legitímne prípady a pokrývajú väčšinu toho, čo uvidíte. Druhý podpisovateľ pridáva svoj podpis. Príjemca vyplňuje polia formulárov, ktoré autor nechal otvorené. A pripája sa materiál dlhodobej validácie: OCSP odpovede a CRL zapísané do document security store dokumentu, aby podpis zostal overiteľný aj po zmiznutí responderov. Toto posledné nie je len povolené, je to, čo dobre spravovaný archív robí s podpísanými dokumentmi zámerne

Takže „súbor narástol po podpise“ nesie žiadnu informáciu. Otázkou vždy je, čo bolo pridané, a odpoveď musí pochádzať z porovnania stavov dokumentu, nie zo sledovania bajtov. Samotnú mechaniku pripájania pokrýva článok o inkrementálnej aktualizácii

Klasifikujte podľa tvaru objektu, nie podľa cesty, ktorá ho vytvorila

Klasifikátor sa pozerá na to, čo objekt je po zmene, nie na to, ktoré volanie knižnice ho vytvorilo. Je to zámerné, pretože analýza beží proti súborom vyrobeným iným softvérom, kde nie je k dispozícii žiadna volacia cesta na preskúmanie

Rozoznáva sa štyri tvary. Slovníky informácií document security store a súvisiace s validáciou, objekty cross-reference stream, položka metadata v katalógu a slovníky podpisov nesúce bajtový rozsah sú materiálom dlhodobého archívu. Objekt nesúci súčasne typ poľa aj hodnotu poľa je vyplňanie formulárov. Objekt, ktorého typ je annotation alebo ktorého subtype je jedným z tých uvedených v tabuľke 168 normy ISO 32000-2, je zmena anotácie. Všetko ostatné je neklasifikované

Rozhodovací strom, ktorý PDFlibPas aplikuje na každý zmenený objekt PDF a zaraďuje aktualizácie na úrovne archív, vyplňanie formulárov, anotácia alebo neklasifikované
Každý zmenený objekt sa klasifikuje podľa toho, čo je — security store, xref stream, pole, anotácia — nikdy podľa volania, ktoré ho vytvorilo

Odstránenia sa posudzujú prísnejšie ako pridania. Odstránený objekt je whitelisted len vtedy, keď objekt na starej strane bol sám archívnym materiálom, čo pokrýva bežný prípad security store nahradeného novším. Každé iné odstránenie je neklasifikované, pretože mazanie obsahu z podpísaného dokumentu nie je niečo, čo by úroveň oprávnení autorizovala. Rozdiely na úrovni dokumentu sú ešte prísnejšie: zmena počtu strán ide priamo na neklasifikovanú bez preskúmania jednotlivých objektov, keďže žiadna úroveň DocMDP nepovoľuje pridávanie či odobratie strán

Whitelist sa mýli smerom k odmietaniu

Toto je návrhové pravidlo, ktoré riadi každé hraničné rozhodnutie. Zmena nesprávne klasifikovaná ako povolená je podpis, ktorý validuje nad obsahom, ktorý autor nikdy neautorizoval. Zmena nesprávne klasifikovaná ako neklasifikovaná je dokument, ktorý dostane príznak a prezrie ho človek. Tieto dve chyby nie sú symetrické, takže whitelist zostáva úzky a nerozpoznané tvary prepadávajú do neklasifikovaných namiesto hádania

To má praktický dôsledok, ktorý stojí za predvídanie: súbory od neobvyklých výrobcov budú niekedy hlásiť neklasifikované zmeny, ktoré sú pri skúmaní neškodné. Správna reakcia je pozrieť sa na detail nálezu a číslo objektu namiesto rozširovania whitelistu, pretože whitelist, ktorý rastie, aby umlčal jednotlivé hlásenia, prestáva byť bezpečnostnou kontrolou

uses
  PDFlibrary, PDFlibCompare;

var
  Pdf: TPDFlib;
  I, Level: Integer;
begin
  Pdf := TPDFlib.Create(nil);
  try
    Pdf.LoadFromFile('contract-countersigned.pdf', '');
    if Pdf.AnalyzeModifications('contract-as-signed.pdf', '') < 0 then
      raise Exception.Create('the earlier revision could not be loaded');

    // TPLModificationLevel v poradí mlNone, mlLTAUpdates, mlFormFilling,
    // mlAnnotations, mlUnclassified; getter vracia jeho ordinal
    Level := Pdf.GetModificationLevel;
    // Vynútenie DocMDP je teraz jedno porovnanie s politikou
    if Level > Ord(mlFormFilling) then
      for I := 0 to Pdf.GetModificationFindingCount - 1 do
        Report.Add(Format('object %d, level %d: %s',
          [Pdf.GetModificationFindingObjNum(I),
           Pdf.GetModificationFindingLevel(I),
           Pdf.GetModificationFindingDetail(I)]));
  finally
    Pdf.Free;
  end;
end;

Celková úroveň je maximum zo všetkých nálezov, čo je jediná obhájiteľná agregácia: dokument obsahujúci deväťdesiatdeväť archívnych pridaní a jednu neklasifikovanú zmenu je neklasifikovaná zmena

Pod tým: odtlačky, nie kryptografické hashe

Porovnávací engine, ktorý vystavuje CompareWith a na ktorom je analýza úprav postavená, identifikuje objekty odtlačkom ich normalizovaného tela pomocou nekryptografického 64-bit hashu namiesto SHA-256. Je to premyslená voľba. To, čo štrukturálne porovnávanie potrebuje, je determinizmus: rovnaké telo objektu musí v rámci behu vždy produkovať rovnaký odtlačok. Nepotrebuje odolnosť voči kolíziám, pretože útočník, ktorý kontroluje obe strany porovnania, už vyhral inými prostriedkami a platenie si za plný kryptografický hash nad každým objektom v dokumente s miliónom objektov je reálna cena bez úžitku

Dve pravidlá normalizácie sú dôležitejšie než voľba hashu. Nepriame odkazy sa skladajú do tokenu placeholder namiesto rozbalenia do odkazovaného obsahu: rozbalenie by skopírovalo telo zdieľaného objektu do každého referrera, takže jedna malá úprava zdieľaného font descriptoru by zneplatnila odtlačok každého objektu, ktorý k nemu siahne, a hlásenie by bolo nečitateľné. A samotné čísla objektov sú z odtlačku vylúčené, pretože prepis môže objekty prečíslovať bez zmeny čohokoľvek semantického

Porovnávanie potom beží v dvoch priechodoch, najprv zarovnávanie podľa odtlačku a zvyšok sa páruje podľa čísla objektu, aby sa identifikovali zmeny namiesto pridania plus odstránenia. Lacné kontroly prichádzajú prvé po celý čas: rozdiel v počte strán sa hlási skôr, než sa začne akékoľvek prechádzanie objektov

Dvojpriechodový diff revízií PDF v PDFlibPas: najprv kontrola počtu strán, 64-bitové odtlačky, zarovnanie odtlačkov a potom párovanie podľa čísel objektov
Porovnávací engine odtlačkuje normalizované telá objektov, hlási najprv rozdiely počtu strán a potom páruje podľa odtlačku a čísla objektu

Pasca: sebakporovnanie nie je garantované ako identické

Prirodzený prvý test pre diff engine je porovnať súbor sám so sebou a tvrdiť, že výsledok je identický. Toto tvrdenie tu neplatí a dôvod je poučný. Verejná cesta načítania a nižšia cesta načítania dokumentu nekonfigurujú dekódovanie identicky, takže ten istý súbor načítaný dvoma cestami môže produkovať odtlačky, ktoré sa pre niektoré objekty líšia. Engine nie je chybný; dve načítania skutočne vyprodukovali rozdielne stavy v pamäti

Namiesto násilného zrutenia oboch ciest sú sémantika porovnania vyjadrené úzko: analýza porovnáva aktuálny stav dokumentu so skoršou revíziou a hlási identické len vtedy, keď sa obe sady odtlačkov presne zhodujú. To je otázka, ktorú používatelia skutočne kladú, a nevyžaduje to, aby oba loadery boli zameniteľné. Keď navrhujete porovnávaciu funkciu, definovanie toho, čo znamená „rovnaké“, je väčšia časť práce než jej vypočítanie

Kde to použiť

Na dvoch miestach. V správe o validácii, popri kontrole podpisov, aby recenzent videl nielen to, či je podpis kryptograficky neporušený, ale aj čo sa s dokumentom stalo potom; strana podpisov je pokrytá v podpisovaní a validácii PAdES. A v intake bráne, kde sa dokument prichádzajúci zvonku kontroluje voči kópii, ktorú ste poslali, takže vrátená zmluva s pridanou anotáciou sa posudzuje odlišne od takej s upravenou stránkou

Jedna poznámka k rozsahu. Táto analýza vám povie, čo sa zmenilo medzi dvoma revíziami tej istej línie dokumentu. Nepovie vám, či je viditeľný obsah zavádzajúci, či appearance stream poľa formulára zodpovedá jeho hodnote alebo či je text skrytý pod overlay stále prítomný v content stream. To potrebuje samostatné zaobchádzanie a strana odstraňovania obsahu je pokrytá v článku o skutočnej redakcii. Vstupné body analýzy a porovnania sú zdokumentované na produktovej stránke losLab PDF Developer Library