HotPDF verifikuje ML-DSA-44, ML-DSA-65, ML-DSA-87, Ed25519 i Ed448 CMS potpise u učitanim PDF dokumentima, i potpisuje kroz priključne provajdere tako da privatni ključ nikada ne mora živeti unutar vašeg Delphi procesa. Ta druga polovina je deo koji većini timova treba prvi. Hardverski token, udaljeni servis za potpisivanje i nacionalna eID kartica sve odbijaju da predaju ključ, i dok se tok potpisivanja ne odvoji od skladišta ključeva, nijedan od njih ne može se uopšte koristiti
To razdvajanje je poenta THPDFSignatureProvider. HotPDF zadržava delove koje treba da poseduje — parsiranje CMS-a, izgradnju SignedData, raspored /ByteRange — i delegira jednu operaciju koju ne može posedovati, a to je pretvaranje izvoda u potpis ključem koji mu nije dozvoljeno da vidi. Sve ispod proizilazi iz te podele
Zašto ispravan ML-DSA potpis ne uspeva u verifikaciji?
Zato što HotPDF odbija ML-DSA na učitanom dokumentu koji ne deklariše proširenje za njega. ML-DSA — schema rešetkastog potpisa standardizovana kao FIPS 204, i razlog zašto ljudi kažu «post-kvantni PDF» — još uvek nema ISO 32000-2 registraciju. PDF koji nosi jedan takav koristi algoritam koji osnovni standard ne imenuje, a fajl koji tiho koristi neimenovani algoritam je fajl čiji verdikt niko drugi ne može reprodukovati
Zato HotPDF čini zahtev eksplicitnim. EnsureMLDSAExtensions podiže dokument na PDF 2.0 gde je dozvoljeno i upisuje /Extensions /HotPDF << /BaseVersion /2.0 /ExtensionLevel 1 >> u Katalog. Na strani čitanja, LoadedDocumentDeclaresMLDSAExtension prijavljuje da li je ta deklaracija preživela, a VerifyLoadedSignatureWithOptions primenjuje istu proveru pre nego što će poštovati Options.AllowMLDSA. Postavite zastavicu na nedeklarisanom dokumentu i ona ostaje isključena — opcija može olabaviti politiku, ali nikada strukturni zahtev
var
Pdf: THotPDF;
begin
Pdf := THotPDF.Create(nil);
try
Pdf.FileName := 'contract-pq.pdf';
Pdf.BeginDoc;
Pdf.CurrentPage.SetFont('Arial', [], 11);
Pdf.CurrentPage.TextOut(50, 720, 0, 'Supply agreement 2026-114');
Pdf.EnsureMLDSAExtensions; // declare before the signature is written
Pdf.EndDoc;
finally
Pdf.Free;
end;
end;
Pozovite ga pre snimanja, ne posle. Deklaracija je deo potpisanog opsega bajtova, a Katalog zakrpan naknadno je ili nepotpisana izmena potpisanog fajla ili druga revizija koju će validator prijaviti kao izmenu
Tri porodice algoritama, jedna ulazna tačka verifikacije
Sve tri porodice dolaze kroz VerifyLoadedSignatureWithOptions, koji uzima indeks potpisa, izvorni tok, THPDFCMSVerifyOptions zapis i izlazni parametar za detalje potpisa. Zapis ima tačno tri polja, i svako odgovara na pitanje koje je nekada zahtevalo ponovnu izgradnju
SignatureProvider zamenjuje ugrađeni platformski provajder vašim sopstvenim. OpenSSLLibraryPath bira OpenSSL 3 biblioteku, koja isporučuje verifikaciju Ed25519 i Ed448 u čistom režimu koju Windows CNG ne nudi svuda. AllowMLDSA opredeljuje se za rešetkaste algoritme, podložno gore navedenoj proveri proširenja. Tačan OID algoritma koji je prepoznat vraća se u THPDFSignatureInfo.SignatureAlgorithmOID, tako da revizijski dnevnik može zabeležiti šta je verifikovano a ne šta je zatraženo
var
Opts: THPDFCMSVerifyOptions;
Info: THPDFSignatureInfo;
Status: THPDFSignatureVerifyStatus;
Src: TFileStream;
begin
Opts := THPDFCMSVerifyOptions.Default;
Opts.OpenSSLLibraryPath := 'C:\openssl3\libcrypto-3-x64.dll';
Opts.AllowMLDSA := Pdf.LoadedDocumentDeclaresMLDSAExtension;
Src := TFileStream.Create('contract-pq.pdf', fmOpenRead or fmShareDenyWrite);
try
Status := Pdf.VerifyLoadedSignatureWithOptions(0, Src, Opts, Info);
if Status = svValid then
Memo1.Lines.Add('signed with OID ' + string(Info.SignatureAlgorithmOID));
finally
Src.Free;
end;
end;
Ed25519 i Ed448 ne trebaju deklaraciju proširenja, jer ih ISO 32000-2 već prima. Treba im provajder koji ih implementira, što na većini Windows primena znači usmeravanje OpenSSLLibraryPath na biblioteku koju isporučujete i kontrolišete, a ne na onu koja se slučajno nađe na mašini
Šta provajder za potpisivanje zapravo obećava?
Provajder obećava jednu stvar: za dat zahtev, vrati status i, pri potpisivanju, bajtove. THPDFSignatureProviderRequest nosi algoritam i njegov OID, OID izvoda, dužinu PSS soli, da li je ulaz poruka ili već izračunat izvod, sam ulaz, javni ključ ili sertifikat, identifikator ključa i identifikator operacije. Ništa u tom zapisu nije specifično za HotPDF — to je rečnik koji drajver tokena ili servis za potpisivanje već govori
Tri implementacije se isporučuju uz biblioteku. THPDFCallbackSignatureProvider obavija anonimne metode, što je najkraći put od postojeće interne rutine potpisivanja do radnog PDF potpisa. THPDFRemoteSignatureProvider obavija callback transporta sa granicom ponavljanja, registrom otkazivanja i ograničenjima ulaza i veličine potpisa, tako da zaglavljen HSM ne može postati zaglavljena aplikacija. THPDFPKCS11SignatureProvider serijalizuje RSA operacije protiv sesije u vlasništvu pozivaoca, već autentifikovane, i ručice privatnog ključa — HotPDF se nikada ne prijavljuje, nikada ne vidi PIN i nikada ne zatvara sesiju koju nije otvorio
var
Provider: THPDFRemoteSignatureProvider;
begin
Provider := THPDFRemoteSignatureProvider.Create(
function(const Req: THPDFSignatureProviderRequest; Attempt: Integer;
out Signature: TBytes): THPDFSignatureProviderStatus
begin
// POST Req.Input to the signing service; Req.KeyIdentifier selects the key
if PostToSigningService(Req.KeyIdentifier, Req.Input, Signature) then
Result := spsValid
else
Result := spsProviderError;
end,
3, // RetryLimit
1048576, // MaxInputBytes
65536); // MaxSignatureBytes
try
// hand Provider to the signing call
finally
Provider.Free;
end;
end;
Zašto enum statusa ima šest vrednosti umesto booleana
THPDFSignatureProviderStatus razlikuje spsValid, spsInvalid, spsUnsupported, spsMalformed, spsProviderError i spsCancelled, a njihovo sažimanje vas košta sposobnosti da delujete ispravno. Potpis koji je kriptografski pogrešan (spsInvalid) jeste bezbednosni događaj. Algoritam koji provajder ne implementira (spsUnsupported) jeste jaz u primeni. Neuspeh transporta (spsProviderError) vredi ponoviti, a korisnički otkazan prompt tokena (spsCancelled) ne vredi ponavljati uopšte
Pravilo za potpisivanje je usko: provajder potpisivanja vraća spsValid samo sa nepraznim potpisom. Provajderi verifikacije vraćaju spsValid ili spsInvalid, a ostale četiri ostaju različite na obe putanje. Ako pišete provajder, oduprite se iskušenju da sve što ne prepoznajete mapirate na spsInvalid — to pretvara nedostajući DLL u izveštaj da je potpis klijenta falsifikovan
Gde potpis zapravo sliše u fajl
Dve funkcije povezuju provajdere sa stvarnim PDF bajtovima. HPDFCMSBuildSignedDataWithProvider gradi odvojeni CMS iz izvoda dokumenta SHA-256, što je prava ulazna tačka kad vaš tok izračunava izvod drugde. HPDFCMSSignPDFStreamWithProvider potpisuje postojeće mesto za potpis u PDF toku i čuva standardni /ByteRange tok, što je prava ulazna tačka kad je HotPDF sam rasporedio mesto za potpis
Očuvanje tog toka je važnije nego što zvuči. Konvencija /ByteRange — dva opsega koja preskaču heks prozor potpisa — jeste ono što svaki validator proverava prvo, a putanja zasnovana na provajderu koja bi je prepisala bi prekinula PAdES usklađenost bez obzira na to koliko bila zdrava kriptografija. HotPDF čuva raspored identičnim ugrađenoj putanji potpisivanja, tako da dokument potpisan kroz PKCS#11 token verifikuje istim kodom za verifikaciju potpisa kao i onaj potpisan iz PFX fajla. Za pravila profila koja sede iznad izbora algoritma, pogledajte prolaz kroz PAdES osnovne potpise u Delphi, a za ECDSA-specifične zamke kodiranja koje prethode ovom modelu provajdera, beleške o ECDSA CMS verifikaciji i P1363 formatima potpisa
Redosled migracije koji ne ostavlja vaše dokumente na cedulju
Post-kvantna spremnost je problem rasporeda, a ne prekidač. Gotovo nijedan primenjeni PDF pregledač danas ne validira ML-DSA, tako da je dokument potpisan samo sa njim, iz ugla čitača, dokument sa potpisom koji se ne može verifikovati. Redosled koji preživljava susret sa stvarnim arhivama je: zadržite RSA ili ECDSA kao potpis koji će validator oceniti, dodajte deklaraciju proširenja i drugi ML-DSA potpis tamo gde politika zahteva dokaz otporan na kvant, i pomerite primarni potpis tek kad potrošački sistemi dostignu taj nivo
Ono što vam HotPDF danas daje jeste sposobnost da pišete i verifikujete oba, iz istog koda, sa algoritmom iskreno zabeleženim u fajlu i u rezultatu verifikacije. HotPDF je nativna VCL PDF komponenta za Delphi i C++Builder bez eksternog PDF izvršnog okruženja, tako da se putanje potpisivanja i verifikacije isporučuju unutar vašeg izvršnog fajla a ne pored njega — pogledajte stranicu HotPDF Delphi PDF komponente za kompletnu listu funkcija i probnu verziju