Esta versão localizada trata de PDF Digital Signatures and PAdES in Delphi with HotPDF usando o artigo em inglês atualizado como referência técnica para equipes Delphi, PDF e software documental
A página transforma a base atualizada em pontos de controle práticos para projeto, implementação e validação
Conteúdo sincronizado a partir da base em inglês
O artigo base foi ampliado com contexto prático, decisões técnicas e exemplos concretos, então esta página deve ser lida como guia de trabalho, não como resumo curto
Pontos importantes da versão atualizada:
- Use primeiro arquivos de entrada pequenos e reproduzíveis
- Mantenha intactos nomes de produto, API, arquivos e valores literais
- Salve a saída do validador e as versões junto com o arquivo de teste gerado
Decisões práticas de implementação
Comece pelo tipo de arquivo, pelo resultado esperado e pelo estado de erro que o usuário precisa ver. Depois conecte cada chamada API a um resultado verificável para que validação, logs e suporte possam reproduzir o caso do cliente
- Use primeiro arquivos de entrada pequenos e reproduzíveis
- Mantenha intactos nomes de produto, API, arquivos e valores literais
- Salve a saída do validador e as versões junto com o arquivo de teste gerado
Código e pontos API
Os exemplos de código são preservados sem alteração para comparação direta com projetos Delphi, C++Builder e Lazarus/FPC
if THotPDF.SignPDFWithPFX('invoice-unsigned.pdf', 'invoice-signed.pdf',
'company-cert.pfx', 'pfx-password') then
Writeln('Signed: invoice-signed.pdf')
else
raise Exception.Create('PFX signing failed');var
Doc: THotPDF;
Fs: TFileStream;
PdfBytes, HashInput, SigHex: AnsiString;
R1Start, R1Len, R2Start, R2Len, CStart, CLen: Integer;
begin
// 1. Write the document with a reserved /Contents hole
Doc := THotPDF.Create(nil);
try
Doc.FileName := 'placeholder.pdf';
Doc.BeginDoc;
Doc.CurrentPage.AddSignedSignatureField('Sig1',
Rect(50, 100, 350, 150), 8192, 'adbe.pkcs7.detached',
'Contract approval', 'Boston, MA', 'legal@example.com');
Doc.EndDoc;
finally
Doc.Free;
end;
// 2. Load the saved bytes; the returned offsets are 0-based
Fs := TFileStream.Create('placeholder.pdf', fmOpenRead);
try
SetLength(PdfBytes, Fs.Size);
Fs.ReadBuffer(PdfBytes[1], Fs.Size);
finally
Fs.Free;
end;
THotPDF.PreparePDFForSigning(PdfBytes, R1Start, R1Len, R2Start, R2Len,
CStart, CLen);
// 3. Hash both spans and sign externally (HSM, token, service)
HashInput := Copy(PdfBytes, R1Start + 1, R1Len) +
Copy(PdfBytes, R2Start + 1, R2Len);
SigHex := SignWithHsm(HashInput); // your integration: returns CMS as hex
// 4. Splice the signature into the reserved hole
THotPDF.InsertSignatureHex(PdfBytes, SigHex);
Fs := TFileStream.Create('signed.pdf', fmCreate);
try
Fs.WriteBuffer(PdfBytes[1], Length(PdfBytes));
finally
Fs.Free;
end;
end;// PAdES baseline signature field (ETSI EN 319 142-1)
Pdf.CurrentPage.AddPAdESSignatureField(
'ApprovalSig', Rect(50, 100, 350, 150), 'B-B',
'Contract approval', 'Boston, MA', 'legal@example.com');
// Document timestamp: larger reservation for the TSA token and chain
Pdf.CurrentPage.AddDocumentTimestampSignature('ArchiveTS', 16384);Verificação antes da publicação
Revise o arquivo de saída com as mesmas ferramentas que o cliente ou o arquivo documental usará. Registre versão do componente, dados de teste, versão do validador e resultado observado