Como proteger e assinar documentos PDF em TypeScript
Este guia mostra como criptografar, certificar, assinar e verificar documentos PDF com Aspose.PDF FOSS para TypeScript. Document.Save() e Document.Open() lidam com criptografia de chave pública para certificados de destinatário, enquanto Document.Certify(), Document.Sign() e Document.VerifySignatures() lidam com assinaturas digitais no estilo PAdES. É necessário Node.js 22 ou superior.
Guia passo a passo
Etapa 1: Instalar o pacote
git clone https://github.com/aspose-pdf-foss/Aspose.PDF-FOSS-for-TypeScript.git
cd Aspose.PDF-FOSS-for-TypeScript
npm install
npm run buildVerifique a instalação importando a classe Document em um novo arquivo TypeScript — esta linha deve ser resolvida sem erro assim que o pacote estiver instalado:
import { Document } from '@asposefoss/pdf';Etapa 2: Importar as classes necessárias
Importe Document para abrir, salvar, assinar e verificar o arquivo; as etapas de assinatura e criptografia abaixo passam objetos de opção simples, portanto não são necessárias outras importações:
import { Document } from '@asposefoss/pdf';Etapa 3: Criptografar um documento para certificados dos destinatários
Document.Save() aceita uma opção encrypt que contém um ou mais recipients, cada um identificado por um certificado (string PEM ou bytes DER), um algorithm, e permissions compartilhados:
const doc = Document.OpenFile('report.pdf');
const bytes = doc.Save({
encrypt: {
recipients: [{ certificate: recipientCertPem }],
algorithm: 'aes256', // 'aes256' (default) | 'aes128' | 'rc4'
permissions: { copying: false }, // shared across all recipients
},
});Etapa 4: Abrir um documento criptografado
Passe uma opção recipient para Document.Open() com a chave privada e o certificado correspondentes, ou um pacote PKCS#12:
const opened = Document.Open(bytes, {
recipient: { privateKey, certificate: recipientCertPem },
// or: recipient: { pkcs12: p12Bytes, passphrase: '…' },
});
console.log(opened.Permissions); // recovered permission flags (not enforced)
Etapa 5: Certificar e assinar um documento
Document.Certify() e Document.Sign() são ambos assíncronos e recebem uma identidade (certificate + privateKey) além de opções que descrevem o campo de assinatura, a aparência e o motivo. A certificação deve ocorrer primeiro, em todo o arquivo; assinaturas de aprovação adicionais são acrescentadas incrementalmente depois:
async function certifyAndSign(sourcePath: string, signaturePageIndex: number): Promise<void> {
const certifying = Document.OpenFile(sourcePath);
await certifying.Certify(
{ certificate: authorCert, privateKey: authorKey },
{
permissions: 'form-fill',
reason: 'Certifying the document',
fieldName: 'Certification',
appearance: { page: signaturePageIndex, rect: [400, 100, 550, 140] },
},
);
const certifiedBytes = certifying.Save();
const approving = Document.Open(certifiedBytes);
await approving.Sign(
{ certificate: approverCert, privateKey: approverKey },
{ reason: 'Approved for publication', fieldName: 'Approval', subFilter: 'PAdES' },
);
approving.WriteTo('signed.pdf');
}Etapa 6: Verificar assinaturas
Document.VerifySignatures() é assíncrono e retorna um SignatureReport por campo de assinatura, cada um relatando criptográfico integrity, validade signature, e se ele coversWholeFile:
async function verify(path: string): Promise<void> {
const doc = Document.OpenFile(path);
const reports = await doc.VerifySignatures();
for (const r of reports) {
console.log(`${r.name}: integrity=${r.integrity} signature=${r.signature} `
+ `coversWholeFile=${r.coversWholeFile} docMDP=${r.docMDP}`);
}
}Problemas Comuns e Correções
Document.Sign() / Document.Certify() lançar ou travar. Ambos são assíncronos — await a chamada. Esquecendo await deixa a promessa retornada sem resolução e a escrita ocorre antes que a assinatura seja concluída.
Uma assinatura de aprovação posterior invalida a certificação. Assine incrementalmente: salve os bytes certificados primeiro (certifying.Save()), reabra-os com Document.Open(), então chame Sign() no documento reaberto — escrever uma reescrita completa em vez de um acréscimo incremental quebra a certificação /ByteRange digest.
VerifySignatures() reports coversWholeFile: false para a primeira assinatura, mas true para a última. Isso é esperado para uma cadeia certificar-então-assinar: a certificação foi assinada antes que a aprovação fosse anexada, de modo que apenas da assinatura mais recente /ByteRange estende até o final do arquivo.
A descriptografia falha mesmo com a chave privada correta. Confirme o certificate passado para recipient corresponde exatamente ao certificado ao qual o documento foi criptografado em Document.Save()de recipients lista — um certificado reemitido com um novo par de chaves não descriptografará dados criptografados sob o antigo.
Perguntas Frequentes
Um documento pode ser criptografado para mais de um destinatário?
Sim — recipients na opção encrypt de Document.Save() aceita um array; a chave privada correspondente de qualquer destinatário pode abrir o arquivo resultante.
Qual formato de assinatura Document.Sign() produz?
Passar subFilter: 'PAdES' nas opções de assinatura produz uma assinatura compatível com PAdES; omiti-lo usa o subfiltro de assinatura padrão da biblioteca.
Como verifico se um documento está certificado ou apenas assinado?
Inspecione o campo docMDP no SignatureReport retornado por Document.VerifySignatures() — uma assinatura de certificação reporta um veredicto de permissão DocMDP; uma assinatura apenas de aprovação não o faz.
Os Permissions recuperados após Document.Open() são aplicados pela biblioteca?
Não — opened.Permissions relata as flags de permissão registradas no arquivo criptografado para inspeção; aplicar essas permissões em uma aplicação é responsabilidade do chamador.