PDF, které jste právě podepsali, je podpis B-B a nic víc. Dokazuje, kdo podepsal, a že se bajty nepohnuly, ale nenese žádný důkaz, že certifikát podepisujícího byl v okamžiku podpisu platný, takže validátor za pár let musí pátrat po datech o revokaci, která už nemusí existovat. Zavřít tuto mezeru znamená zapsat odpovědi OCSP a CRL na úrovni dokumentu do Document Security Store a v HotPDF je to jedno volání: PopulatePAdESLTVEvidence projde každý načtený podpis, odvodí revokační žádosti ze sady certifikátů, provede je transportem, který dodáte, a zapíše získaný materiál plus řetězec CMS do DSS. Vrací počet podpisů, jejichž důkazy dopadly, nebo minus jedna, když dokument nemá vůbec podpisové pole
Návrhové rozhodnutí, které stojí za pochopení, než ji použijete, je, že knihovna nikdy neotevře soket. Každý bajt, který dorazí ze sítě, dorazí přes callback, který jste napsali. Není to obezřetnost pro obězřetnost; je to jediný způsob, jak může tato funkce fungovat uvnitř prostředí, která dlouhodobé ověřování skutečně vyžadují
Proč knihovna odmítá dělat vlastní HTTP?
Protože místa, která vyžadují podpisy B-LT, jsou místa, kde nelze knihovně sít věřit. Služby podepisování běží za autentizujícími proxy s firemními kořeny. Odpojené podepisující vrstvy nemají cestu k responderovi a musí být krmeny cachovanými důkazy. Auditní režimy vyžadují, aby každý odchozí požadavek logovala aplikace, nikoli pohřbená závislost. A testovací sady potřebují deterministické odpovědi, což je nemožné, pokud si knihovna volá na vlastní pěst
Transport je prostý odkaz na funkci s pevným tvarem, takže politika zůstává vaše. HotPDF vám podá záznam žádosti popisující přesně, co stáhnout, včetně typu obsahu a stropu velikosti odpovědi, a vy vrátíte bajty plus stav
function FetchEvidence(const Request: THPDFSignatureEvidenceRequest;
Attempt: Integer; CancellationToken: THPDFCancellationToken;
out Response: TBytes; out RetryAfterMS: Cardinal;
out ErrorMessage: UnicodeString): THPDFSignatureEvidenceTransportStatus;
begin
RetryAfterMS := 0;
try
// Request.Kind říká, zda jde o OCSP POST nebo CRL GET;
// Request.ContentType a Request.Body jsou už připraveny,
// a Request.MaxResponseBytes je strop, který musíte respektovat
Response := HttpExchange(Request.URI, Request.ContentType,
Request.Body, Request.MaxResponseBytes);
Result := setsSucceeded;
except
on E: Exception do
begin
ErrorMessage := E.Message;
// setsRetry nechá politiku opakování ustoupit; použijte
// setsPermanentFailure pro 404 nebo špatnou URL
Result := setsRetry;
end;
end;
end;
// Povýšení B-B na B-LT jediným voláním pro každý podpis v načteném souboru
var
Pdf: THotPDF;
Upgraded: Integer;
begin
Pdf := THotPDF.Create(nil);
try
Pdf.BeginIncrementalUpdate('signed.pdf');
Upgraded := Pdf.PopulatePAdESLTVEvidence(FetchEvidence,
THPDFSignatureEvidenceRetryPolicy.Default);
if Upgraded > 0 then
// Uložení jen přidáváním: bajty, které existující podpisy
// pokrývají, zůstávají zachovány doslova
Pdf.SaveIncrementalUpdate('signed-lt.pdf');
finally
Pdf.Free;
end;
end;
Selhání jsou na úrovni jednotlivých podpisů, nikoli dokumentu. Responder, který vyčerpá timeout pro jednoho podepisujícího, vynechá materiál tohoto podepisujícího a zbytek průchodu zanechá nedotčený, což je chování, které v dávce chcete: částečné důkazy jsou lepší než přerušený běh a návratová hodnota vám řekne, kolik podpisů se skutečně zlepšilo
Řetězec, na který CMS zapomněl
Kontrola revokace potřebuje certifikát vydavatele a překvapivý počet podpisových stacků vynechává intermediáty z kontejneru CMS. Cesta záchrany je rozšíření Authority Information Access, metoda přístupu 1.3.6.1.5.5.7.48.2, která inzeruje URL, odkud lze certifikát vydavatele stáhnout. HPDFFetchAIAIntermediates projde tyto URL stejným transportem, vyparsuje DER z každé odpovědi a vrátí jen certifikáty, které CMS už nenosil, klíčované hašem DER, aby duplikáty a cykly nemohly rotovat
Dva detaily rozhodují, zda to funguje proti skutečným certifikačním autoritám. První je kódování: koncové body CA podávají certifikát jako holý DER zhruba stejně často jako v PEM zbroji a neexistuje spolehlivý typ obsahu k jejich rozlišení. Robustní sonda je textová, pak strukturální. Hledejte značku -----BEGIN CERTIFICATE-----, sejměte zbroj a dekódujte base64, je-li přítomna, a v obou cestách potvrďte, že první bajt výsledku je $30, DER značka pro SEQUENCE. Druhé je hloubka: získaný intermediát sám může inzerovat AIA URL pro vlastního vydavatele, takže průchod přidává nové kandidáty do fronty a doplňuje řetězce, kterým chybí dvě či tři skoky. To je nutné omezit, k čemuž slouží parametr MaxFetch
Co je seed value podpisu a proč selhává potichu?
Seed value je omezení, které autor dokumentu připojuje k podpisovému poli, aby řekl podepisujícímu, jaký druh podpisu je přijatelný: který SubFilter, který hašovací algoritmus, jaké důvody, jaká minimální verze PDF, zda musí být revokační informace vloženy. Žije ve slovníku /SV na poli a je definována v ISO 32000-1 §12.7.5.5. HotPDF ji zapisuje pomocí AttachPAdESSeedValue a kontroluje pomocí CheckLoadedSignatureSeedValue, která vrací True, když je pole bez omezení nebo projde každé přítomné omezení, a při False jmenuje první selhávající omezení přes výstupní parametr, který můžete dát rovnou do chybové zprávy
Mechanismem, který dělá seed values snadno pokazitelnými, je položka příznaků /Ff popsaná v §12.7.5.5.3. Nastavený bit označuje své omezení jako vyžadované: nesoulad je chyba a podepisující musí odmítnout. Vynulovaný bit označuje totéž omezení jako preferenci: hodnota filtruje, co by uživatelské rozhraní mělo nabízet, a nic víc. Z toho plynou dvě pasti. Za prvé, /Ff žije uvnitř slovníku /SV, nikoli na anotaci widgetu, takže kód čtoucí /Ff na úrovni pole dostává navždy prázdnou odpověď a usoudí, že nic není vynuceno. Za druhé, přiřazení bitů není jednoduchá řada jedna, dva, čtyři, osm; v HotPDF vypisuje writer 2 pro SubFilter, 4 pro MinVersion, 32 pro AddRevInfo a 64 pro DigestMethod. Čtečka předpokládající sekvenční bity dekóduje každé omezení jako volitelné a projde každým testem kromě toho jediného, který se počítá
var
Violation: AnsiString;
begin
// Zeptejte se pole, zda je profil, s nímž se chystáme podepsat, povolen
if not Pdf.CheckLoadedSignatureSeedValue(0, 'ETSI.CAdES.detached',
'SHA256', 'Approved for payment', 1, Violation) then
raise Exception.Create('Signature field rejects this profile: ' +
String(Violation));
// Omezení splněno: pokračujte podpisovým průchodem
end;
Test, který odhalil původní chybu dekódování, nebyl pozitivní test. Byla to aserce, že vynucený nesoulad musí být odmítnut, a je to jediný druh testu, který dokáže tuto třídu defektů chytit: dekodér čtoucí špatný slovník nebo špatné pozice bitů produkuje „žádná omezení porušena“ pro každý vstup, což vypadá přesně jako správné chování, dokud jedno záměrně neporušíte
Kde to stojí na žebříčku LTV
Čtyři příčky a každá potřebuje tu pod ní. B-B je holý podpis. B-T přidává důvěryhodné časové razítko, které fixuje čas podpisu, takže validátor ví, ke kterému okamžiku posoudit revokaci. B-LT přidává revokační důkazy do DSS, což je to, co PopulatePAdESLTVEvidence automatizuje. B-LTA přidává časová razítka dokumentu obnovovaná dříve, než oslabí předchozí, čímž prodlužuje platnost do nekonečna; HotPDF vystavuje RenewPAdESLTATimestamp, které připojuje nové razítko jako inkrementální revizi a zachovává každý dřívější podpis, razítko a položku DSS nedotčené
Model inkrementálních aktualizací je jediný správný způsob, jak přidat důkazy do podepsaného dokumentu, protože přepsání souboru by rozbilo bajtové rozsahy, které existující podpisy pokrývají. Pokud potřebujete uvažovat o tom, co se mezi revizemi změnilo, a zda jsou tyto změny toho druhu, který podpis dovoluje, je tato analýza zvlášť předmětem analýzy revizí DocMDP a FieldMDP. Samotné podpisové potrubí, včetně zdrojů certifikátů a pastí pořadí bajtů, je v průvodci podepisováním PAdES a validační strana je v ověřování podpisů na načtených dokumentech
Jedno praktické varování ohledně pořadí. Sbírejte důkazy co nejdříve po podpisu, ideálně v téže úloze. Respondéři, kteří dokáží odpovědět za certifikát, jsou online, dokud je certifikát aktuální, a za pár let jsou pryč, takže dokument, který opustí vaše potrubí jako B-B, už nemusí být nikdy upgradovatelný. HotPDF běží jako nativní komponenta VCL pro Delphi a C++Builder a celý důkazní průchod je v procesu kromě vašeho vlastního transportu; podporované profily jsou uvedeny na stránce produktu HotPDF Delphi PDF component