HotPDF varmentaa ML-DSA-44-, ML-DSA-65-, ML-DSA-87-, Ed25519- ja Ed448-CMS-allekirjoitukset ladatuissa PDF-asiakirjoissa, ja se allekirjoittaa liitettävien tarjoajien läpi niin että yksityisen avaimen ei koskaan tarvitse elää Delphi-prosessisi sisällä. Jälkimmäinen puolikas on se osa jota useimmat tiimit tarvitsevat ensimmäisenä. Laitteistotoken, etäallekirjoituspalvelu ja kansallinen eID-kortti kaikki kieltäytyvät luovuttamasta avainta, ja kunnes allekirjoitusputki on erotettu avainsäilöstä, mitään niistä ei voi käyttää lainkaan
Tuo jako on koko THPDFSignatureProvider:n pointti. HotPDF pitää ne osat joita sen tulisi omistaa — CMS:n jäsennyksen, SignedDatan rakentamisen, /ByteRange:n asettelun — ja delegoi sen yhden operaation jota se ei voi omistaa, eli tiivisteen muuttamisen allekirjoitukseksi avaimella jota sen ei sallita nähdä. Kaikki alla seuraava seuraa tuosta jaosta
Miksi kelvollinen ML-DSA-allekirjoitus epäonnistuu varmentuessa?
Koska HotPDF kieltäytyy ML-DSA:sta ladatussa asiakirjassa joka ei julista sille tehtyä laajennusta. ML-DSA — hilsitalgoritmi joka standardoitiin FIPS 204:ssä, ja syy miksi ihmiset sanovat "post-kvantti-PDF" — ei ole vielä ISO 32000-2-rekisteröity. PDF joka kantaa sitä käyttää algoritmia jota perusstandardi ei nimeä, ja tiedosto joka hiljaa käyttää nimeämätöntä algoritmia on tiedosto jonka tuomiota kukaan muu ei voi toistaa
Niinpä HotPDF tekee vaatimuksen nimenomaiseksi. EnsureMLDSAExtensions nostaa asiakirjan PDF 2.0:een kun se sallitaan ja kirjoittaa /Extensions /HotPDF << /BaseVersion /2.0 /ExtensionLevel 1 >> Katalogiin. Lukemispuolella LoadedDocumentDeclaresMLDSAExtension raportoi säilyikö tuo julistus, ja VerifyLoadedSignatureWithOptions soveltaa samaa testiä ennen kuin se kunnioittaa Options.AllowMLDSA:a. Aseta lippu julistamattomalle asiakirjalle ja se pysyy pois — optio voi löysätä käytäntöä, ei koskaan rakenteellista vaatimusta
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;
Kutsu sitä ennen tallennusta, ei jälkeen. Julistus on osa allekirjoitettua tavu-aluetta, ja jälkikäteen paikattu Katalogi on joko allekirjoittamaton muutos allekirjoitettuun tiedostoon tai toinen revisio jonka validaattori raportoi muutoksena
Kolme algoritmiperhettä, yksi varmennustulopaikka
Kaikki kolme perhettä saapuvat VerifyLoadedSignatureWithOptions:n läpi, joka ottaa allekirjoitusindeksin, lähdevirran, THPDFCMSVerifyOptions-tietueen ja out-parametrin allekirjoitustiedoille. Tietueessa on tasan kolme kenttää, ja jokainen vastaa kysymykseen joka aiemmin vaati uudelleenkäännöksen
SignatureProvider korvaa sisäänrakennetun alustakohtaisen oman tarjoajasi kanssa. OpenSSLLibraryPath valitsee OpenSSL 3 -kirjaston, joka on se mikä toimittaa puhtaassa tilassa olevan Ed25519- ja Ed448-varmennuksen jota Windows CNG ei tarjoa kaikkialla. AllowMLDSA:a optaa hilikkualgoritmeihin yllä olevan laajennustarkistuksen alaisena. Tunnistettu tarkka algoritmi-OID palautuu kentässä THPDFSignatureInfo.SignatureAlgorithmOID, jotta auditointiloki voi tallentaa mikä varmennettiin eikä sitä mitä pyydettiin
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 ja Ed448 eivät vaadi laajennusjulistusta, koska ISO 32000-2 jo hyväksyy ne. Ne vaativat kuitenkin tarjoajan joka toteuttaa ne, mikä useimmissa Windows-käyttöönoissa tarkoittaa OpenSSLLibraryPath:n osoittamista kirjastoon jonka toimitat ja hallitset sen sijaan että se olisi koneelta sattumalta löytyvä
Mitä allekirjoitustarjoaja oikein lupaa?
Tarjoaja lupaa yhden asian: annettua pyyntöä kohden palauta tila ja, allekirjoitettaessa, tavut. THPDFSignatureProviderRequest kantaa algoritmin ja sen OID:n, tiiste-OID:n, PSS-suolapituuden, onko syöte viesti vai jo laskettu tiiste, itse syötteen, julkisen avaimen tai sertifikaatin, avaimen tunnisteen ja operaation tunnisteen. Mikään tuossa tietueessa ei ole HotPDF-kohtaista — se on sanasto jota token-ajuri tai allekirjoituspalvelu jo puhuu
Kolme toteutusta toimitetaan kirjaston mukana. THPDFCallbackSignatureProvider kietoo anonyymit metodit, mikä on lyhin polku olemassa olevasta talon sisäisestä allekirjoitusrutiinistä toimivaan PDF-allekirjoitukseen. THPDFRemoteSignatureProvider kietoo kuljetus-callbackin uudelleenyritysrajalla, peruutusrekisterillä ja rajoilla syöte- ja allekirjoituskoolle, jottei jumiutunut HSM voi muuttua jumiutuneeksi sovellukseksi. THPDFPKCS11SignatureProvider sarjoi RSA-operaatiot kutsujan omistamaan, jo todennettuun PKCS#11-istuntoon ja yksityisen avaimen kahvaan — HotPDF ei koskaan kirjaudu sisään, ei näe PIN:iä eikä sulje istuntoa jota se ei avannut
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;
Miksi tilaenumeraatiossa on kuusi arvoa booleanin sijaan
THPDFSignatureProviderStatus erottaa spsValid, spsInvalid, spsUnsupported, spsMalformed, spsProviderError ja spsCancelled, ja niiden yhdistäminen maksaa sinulta kyvyn toimia oikein. Kryptografisesti väärä allekirjoitus (spsInvalid) on turvallisuustapahtuma. Algoritmi jota tarjoaja ei toteuta (spsUnsupported) on käyttöönottokuilu. Kuljetushäiriö (spsProviderError) on uudelleenyrityksen arvoinen, ja käyttäjän peruuttama token-kehote (spsCancelled) ei ole uudelleenyrityksen arvoinen lainkaan
Sääntö allekirjoittamiselle on kapea: allekirjoitustarjoaja palauttaa spsValid:n vain ei-tyhjällä allekirjoituksella. Varmennustarjoajat palauttavat spsValid:n tai spsInvalid:n, ja muut neljä pysyvät erillään molemmilla poluilla. Jos kirjoitat tarjoajan, vastusta kiusausta kartoittaa kaikki tunnistamasi spsInvalid:een — se muuttaa puuttuvan DLL:n raportiksi jonka mukaan asiakkaan allekirjoitus on väärennetty
Mihin allekirjoitus oikeasti päätyy tiedostossa
Kaksi funktiota yhdistävät tarjoajat oikeisiin PDF-tavuihin. HPDFCMSBuildSignedDataWithProvider rakentaa irrotetun CMS:n asiakirjan SHA-256-tiisteestä, mikä on oikea tulopaikka kun työnkulkusi laskee tiisteen muualla. HPDFCMSSignPDFStreamWithProvider allekirjoittaa olemassa olevan allekirjoituspaikkamerkin PDF-virrassa ja säilyttää standardin /ByteRange-putken, mikä on oikea tulopaikka kun HotPDF asetteli paikkamerkin itse
Tuo putken säilyttäminen merkitsee enemmän kuin miltä kuulostaa. /ByteRange-käytäntö — kaksi aluetta jotka ohittavat hex-allekirjoitusikkunan — on se minkä jokainen validaattori tarkistaa ensimmäisenä, ja tarjoajapohjainen polku joka kirjoittaisi sen uudelleen rikkoisi PAdES-vaatimustenvastaisuuden riippumatta siitä kuinka terve kryptografia oli. HotPDF pitää asettelun identtisenä sisäänrakennetun allekirjoituspolun kanssa, joten asiakirja joka allekirjoitettiin PKCS#11-tokenin läpi varmennetaan samalla allekirjoituksen varmennuskoodilla kuin PFX-tiedostosta allekirjoitettu. Profiilisäännöt jotka istuvat algoritmivalinnan yläpuolella on katso artikkeli PAdES-perustason allekirjoitukset Delphissä, ja ECDSA-kohtaiset koodausansat jotka edelsivät tätä tarvojmallia on muistiinpanoissa ECDSA CMS -varmennus ja P1363-allekirjoitusmuodot
Siirtymäjärjestys joka ei jätä asiakirjojasi rannalle
Post-kvanttivalmius on aikatauluongelma, ei kytkin. Lähes yksikään käytössä oleva PDF-katselin ei varmenna ML-DSA:ta tänään, joten asiakirja joka on allekirjoitettu yksinomaan sillä on lukijan näkökulmasta asiakirja jolla ei ole varmennettavaa allekirjoitusta. Järjestys joka selviää kontaktista todellisten arkistojen kanssa on: pidä RSA tai ECDSA allekirjoituksena jonka validaattori tuomitsee, lisää laajennusjulistus ja toinen ML-DSA-allekirjoitus missä käytäntö vaatii kvantti kestävää näyttöä, ja siirry ensisijaiseen allekirjoitukseen vasta kun käyttävät järjestelmät ovat saavuttaneet
Mitä HotPDF antaa sinulle tänään on kyky kirjoittaa ja varmentaa molemmat, samasta koodista, algoritmin tallennettuna rehellisesti tiedostoon ja varmennustulokseen. HotPDF on natiivi VCL PDF -komponentti Delphille ja C++Builderille ilman ulkoista PDF-ajonaikaa, joten allekirjoitus- ja varmennuspolut toimitetaan suoritettavan tiedostosi sisällä sen vierellä olemisen sijaan — katso HotPDF Delphi PDF -komponenttisivulta koko ominaisuusluettelo ja kokeiluversio