Cómo asegurar y firmar documentos PDF en TypeScript
Esta guía muestra cómo cifrar, certificar, firmar y verificar documentos PDF con Aspose.PDF FOSS para TypeScript. Document.Save() y Document.Open() gestionan el cifrado de clave pública a los certificados del destinatario, mientras que Document.Certify(), Document.Sign() y Document.VerifySignatures() gestionan firmas digitales al estilo PAdES. Requiere Node.js 22 o posterior.
Guía paso a paso
Paso 1: Instalar el paquete
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 la instalación importando la clase Document en un nuevo archivo TypeScript — esta línea debería resolverse sin errores una vez que el paquete esté instalado:
import { Document } from '@asposefoss/pdf';Paso 2: Importar clases necesarias
Importa Document para abrir, guardar, firmar y verificar el archivo; los pasos de firma y cifrado a continuación pasan objetos de opciones simples, por lo que no se requieren más importaciones:
import { Document } from '@asposefoss/pdf';Paso 3: Cifrar un documento con certificados del destinatario
Document.Save() acepta una opción encrypt que lleva uno o más recipients, cada uno identificado por un certificado (cadena PEM o bytes DER), un algorithm, y permissions compartidos:
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
},
});Paso 4: Abrir un documento cifrado
Pasa una opción recipient a Document.Open() con la clave privada y el certificado coincidentes, o un paquete 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)
Paso 5: Certificar y firmar un documento
Document.Certify() y Document.Sign() son ambos asíncronos y aceptan una identidad (certificate + privateKey) más opciones que describen el campo de firma, la apariencia y el motivo. La certificación debe realizarse primero, sobre todo el archivo; las firmas de aprobación adicionales se añaden incrementalmente después:
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');
}Paso 6: Verificar firmas
Document.VerifySignatures() es asíncrono y devuelve un SignatureReport por campo de firma, cada uno informando integrity criptográfico, validez de signature, y si 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 comunes y soluciones
Document.Sign() / Document.Certify() lanzar o colgar. Ambos son asíncronos — await la llamada. Olvidando await deja la promesa devuelta sin resolver y la escritura ocurre antes de que la firma se complete.
Una firma de aprobación posterior invalida la certificación. Firmar incrementalmente: guarda primero los bytes certificados (certifying.Save()), reábralos con Document.Open(), entonces llama Sign() en ese documento reabierto — escribir una reescritura completa en lugar de una adición incremental rompe la certificación /ByteRange resumen.
VerifySignatures() reports coversWholeFile: false para la primera firma pero true para la última. Esto es esperado para una cadena certify-then- sign: la certificación se firmó antes de que se añadiera la aprobación, por lo que solo la firma más reciente de /ByteRange se extiende hasta el final del archivo.
El descifrado falla con la clave privada correcta. Confirma el certificate pasado a recipient coincide con el certificado exacto al que se cifró el documento en Document.Save()de recipients lista — un certificado reemitido con un nuevo par de claves no descifrará los datos cifrados con el anterior.
Preguntas frecuentes
¿Puede un documento cifrarse para más de un destinatario?
Sí — recipients en la opción encrypt de Document.Save() acepta una matriz; la clave privada coincidente de cualquier destinatario puede abrir el archivo resultante.
¿Qué formato de firma produce Document.Sign()?
Pasar subFilter: 'PAdES' en las opciones de firma produce una firma compatible con PAdES; omitirlo usa el subfiltro de firma predeterminado de la biblioteca.
¿Cómo puedo comprobar si un documento está certificado o solo firmado?
Inspeccione el campo docMDP en el SignatureReport devuelto por Document.VerifySignatures() — una firma de certificación informa un veredicto de permiso DocMDP; una firma solo de aprobación no lo hace.
¿Se aplican los Permissions recuperados después de Document.Open() por la biblioteca?
No — opened.Permissions informa los indicadores de permiso registrados en el archivo cifrado para su inspección; hacer cumplirlos en una aplicación es responsabilidad del llamador.