Een PDF die u net heeft ondertekend is een B-B-handtekening en niets meer. Die bewijst wie heeft ondertekend en dat de bytes niet zijn verplaatst, maar die draagt geen bewijs dat het ondertekenaarscertificaat op het moment van ondertekening geldig was, dus een validator die jaren later kijkt moet op zoek naar intrekkingsgegevens die misschien niet meer bestaan. Dat gat dichten betekent OCSP-antwoorden en CRLs in de documentniveau-Document Security Store wegschrijven, en in HotPDF is dat één aanroep: PopulatePAdESLTVEvidence loopt langs elke geladen handtekening, leidt de intrekkingsverzoeken af uit de certificaatset, voert ze uit via een transport dat u aanlevert en schrijft het opgehaalde materiaal plus de CMS-keten in de DSS. Die geeft het aantal handtekeningen terug waarvan het bewijs is geland, of min één wanneer het document helemaal geen handtekeningveld heeft
De ontwerpbeslissing die het begrijpen waard is voordat u die gebruikt, is dat de bibliotheek nooit een socket opent. Elke byte die van het netwerk komt, komt binnen via een callback die u heeft geschreven. Dat is geen voorzichtigheid om de voorzichtigheid; het is de enige manier waarop deze functie kan werken in de omgevingen die langetermijnvalidatie daadwerkelijk eisen
Waarom weigert de bibliotheek eigen HTTP te doen?
Omdat de plekken die B-LT-handtekeningen eisen de plekken zijn waar een bibliotheek niet met het netwerk kan worden vertrouwd. Ondertekendiensten draaien achter authenticerende proxies met bedrijfsroots. Luchtdichte ondertekenlagen hebben geen route naar een responder en moeten gevoed worden met gecachte bewijzen. Auditregimes eisen dat elk uitgaand verzoek door de applicatie wordt gelogd, niet begraven in een afhankelijkheid. En testsuites hebben deterministische antwoorden nodig, wat onmogelijk is als de bibliotheek zelfstandig uitbelt
Het transport is een kale functiereferentie met een vaste vorm, dus het beleid blijft van u. HotPDF geeft u een verzoekrecord mee dat exact omschrijft wat opgehaald moet worden, inclusief het contenttype en een cap op de antwoordgrootte, en u geeft de bytes plus een status terug
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 zegt of dit een OCSP POST of een CRL GET is;
// Request.ContentType en Request.Body zijn al klaargezet,
// en Request.MaxResponseBytes is de cap die u moet respecteren
Response := HttpExchange(Request.URI, Request.ContentType,
Request.Body, Request.MaxResponseBytes);
Result := setsSucceeded;
except
on E: Exception do
begin
ErrorMessage := E.Message;
// setsRetry laat het retrybeleid wachten; gebruik
// setsPermanentFailure voor een 404 of een slechte URL
Result := setsRetry;
end;
end;
end;
// B-B naar B-LT-upgrade in één aanroep voor elke handtekening in het geladen bestand
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
// Alleen-toevoegen-opslag: de bytes die de bestaande handtekeningen
// dekken blijven woord voor woord behouden
Pdf.SaveIncrementalUpdate('signed-lt.pdf');
finally
Pdf.Free;
end;
end;
Fouten gelden per handtekening, niet per document. Een responder die voor één ondertekenaar een timeout geeft, slaat het materiaal van die ondertekenaar over en laat de rest van de passe intact, wat precies het gedrag is dat u in een batch wilt: partieel bewijs verslaat een afgebroken run, en de returnwaarde vertelt u hoeveel handtekeningen er werkelijk zijn verbeterd
De keten die de CMS vergat mee te sturen
Intrekkingscontrole heeft het uitgeverscertificaat nodig, en een verassend aantal ondertekenstacks laat intermediates weg uit de CMS-container. De herstelroute is de Authority Information Access-extensie, access method 1.3.6.1.5.5.7.48.2, die een URL adverteert waar het uitgeverscertificaat gedownload kan worden. HPDFFetchAIAIntermediates loopt die URLs af via hetzelfde transport, parseert de DER uit elk antwoord en geeft alleen de certificaten terug die de CMS nog niet droeg, gesleuteld op DER-hash zodat duplicaten en lussen niet kunnen ronddraaien
Twee details bepalen of dit tegen echte certificeringsinstanties werkt. De eerste is codering: CA-eindpunten serveren het certificaat net zo vaak als kale DER als PEM-gepantserd, en er is geen betrouwbaar contenttype om ze te onderscheiden. De robuuste sonde is eerst tekstueel en dan structureel. Zoek naar de markering -----BEGIN CERTIFICATE-----, haal het pantser eraf en decodeer base64 als die aanwezig is, en bevestig in beide paden dat de eerste byte van het resultaat $30 is, de DER-tag voor een SEQUENCE. De tweede is diepte: een opgehaalde intermediate kan zelf een AIA-URL adverteren voor zijn eigen uitgever, dus de wandeling voegt nieuwe kandidaten toe aan de wachtrij en maakt ketens af die twee of drie sprongen tekortkomen. Dat moet worden begrensd, en daarvoor is de parameter MaxFetch er
Wat is een signatuur-seed value, en waarom faalt die geruisloos?
Een seed value is een beperking die de documentauteur aan een handtekeningveld hangt om de ondertekenaar te vertellen welk soort handtekening acceptabel is: welke SubFilter, welk digest-algoritme, welke redenen, welke minimale PDF-versie, of intrekkingsinformatie ingebed moet zijn. Die staat in een /SV-woordenboek op het veld en is gedefinieerd in ISO 32000-1 §12.7.5.5. HotPDF schrijft die met AttachPAdESSeedValue en controleert die met CheckLoadedSignatureSeedValue, die True teruggeeft wanneer het veld onbeperkt is of elke aanwezige beperking slaagt, en bij False de eerste falende beperking benoemt via een outputparameter die u rechtstreeks in een foutmelding kunt zetten
De mechaniek die seed values foutgevoelig maakt is de /Ff-vlaggeningang die in §12.7.5.5.3 wordt beschreven. Een gezette bit markeert zijn beperking als verplicht: een mismatch is een fout en de ondertekenaar moet weigeren. Een kale bit markeert dezelfde beperking als voorkeur: de waarde filtert wat de UI zou moeten aanbieden en niets meer. Daaruit volgen twee valkuilen. Ten eerste leeft /Ff binnen het /SV-woordenboek, niet op de widgetannotatie, dus code die de veldniveau-/Ff leest krijgt eeuwig een leeg antwoord en concludeert dat niets verplicht is. Ten tweede zijn de bittoewijzingen geen simpele reeks van een, twee, vier, acht; in HotPDF zendt de writer 2 uit voor SubFilter, 4 voor MinVersion, 32 voor AddRevInfo en 64 voor DigestMethod. Een lezer die opeenvolgende bits aanneemt decodeert elke beperking als optioneel en slaagt voor elke test behalve de enige die telt
var
Violation: AnsiString;
begin
// Vraag het veld of het profiel waarmee we gaan ondertekenen is toegestaan
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));
// Beperking gehonoreerd: ga verder met de ondertekenpasse
end;
De test die de oorspronkelijke decodeerbug aan het licht bracht was geen positieve test. Het was de assertie dat een verplichte mismatch geweigerd moet worden, en het is de enige soort test die dit soort defecten kan vangen: een decoder die het verkeerde woordenboek of de verkeerde bitposities leest produceert voor elke input "geen beperking geschonden", wat er exact uitziet als correct gedrag totdat u er bewust één schendt
Waar dit op de LTV-ladder staat
Vier sporten, en elke sport heeft de onder hem nodig. B-B is de kale handtekening. B-T voegt een vertrouwd tijdstempel toe, die de ondertekentijd fixeert zodat een validator weet tegen welk moment intrekking beoordeeld moet worden. B-LT voegt het intrekkingsbewijs aan de DSS toe, en dat is wat PopulatePAdESLTVEvidence automatiseert. B-LTA voegt documenttijdstempels toe die worden vernieuwd voordat de vorige verzwakt, wat de geldigheid onbeperkt verlengt; HotPDF stelt dat bloot als RenewPAdESLTATimestamp, die een nieuwe tijdstempel als incrementele revisie toevoegt en elke eerdere handtekening, tijdstempel en DSS-ingang onaangetast laat
Een incrementeel-update-model is de enige correcte manier om bewijs aan een ondertekend document toe te voegen, want het bestand herschrijven zou de bytebereiken breken die de bestaande handtekeningen dekken. Als u moet redeneren over wat er tussen revisies is veranderd en of die veranderingen het soort zijn dat een handtekening toestaat, dan wordt die analyse apart behandeld in de DocMDP- en FieldMDP-revisieanalyse. De ondertekenpijplijn zelf, inclusief certificaatbronnen en bytevolgorde-valkuilen, staat in de PAdES-ondertekenwalkthrough, en de validatiekant staat in handtekeningen op geladen documenten verifiëren
Eén praktische waarschuwing over de volgorde. Verzamel bewijs zo snel mogelijk na het ondertekenen, bij voorkeur in dezelfde taak. De responders die voor een certificaat kunnen antwoorden zijn online zolang het certificaat actueel is en jaren later verdwenen, dus een document dat uw pijplijn verlaat als B-B is misschien nooit meer opwaardeerbaar. HotPDF draait als een native VCL-component voor Delphi en C++Builder, en de hele bewijspasse verloopt in-proces behalve uw eigen transport; de ondersteunde profielen staan op de productpagina van de HotPDF Delphi PDF component