Firmar digitalmente un documento PDF

Desambiguación importante: Firmar un PDF

Los desarrolladores suelen preguntar cómo pueden añadir mediante programación una firma a un documento PDF utilizando IronPDF. Por lo general, firmar significa cosas diferentes para distintos desarrolladores:

  1. Para firmar digitalmente un documento PDF con un certificado que garantice que no ha sido manipulado.
  2. Para añadir una imagen gráfica de firma manuscrita a un PDF existente desde un archivo de imagen.
  3. Para estampar la imagen de un certificado en un PDF.
  4. Para añadir un campo de formulario de firma a un PDF que algunos visores pueden solicitar que se firme.

    Biblioteca NuGet C# para PDF

    Instalar con NuGet

    Install-Package IronPdf
    o
    Java PDF JAR

    Descargar DLL

    Descargar DLL

    Instalar manualmente en su proyecto

Firmar un PDF con un certificado digital

IronPDF admite muchas formas de firmar un PDF con un certificado de firma digital de los formatos .pfx y .p12. En esta guía práctica, se le guiará a través de los tres métodos principales utilizados para firmar digitalmente documentos PDF:

Método de firmaDescripción
FirmeFirme a PDF with a PdfFirmeature object
FirmeWithFileFirme PDF with a digital signature certificate(.pfx or .p12) on disk
FirmeWithStoreFirmes the PDF with digital signature extracted from your computer's signature storage. Basado en una huella dactilar

Archivos de certificado de firma digital admitidos

Cumplimos oficialmente la norma X509Certificate2 y admitimos las firmas .pfx y .p12. Si su firma no puede ser aplicada directamente en los métodos de firma de IronPDF, necesitará crear un certificado X509Certificate2 con las instrucciones que puede encontrar aquí.

Firmar: Crear FirmaPdf a partir de X509Certificado2

Los métodos de firma de IronPDF aceptarán la variable X509Certificate2 con X509KeyStorageFlags establecida en Exportable.

*Nota

  • IronPDF sólo admite X509KeyStorageFlags.Exportable. Algunos certificados tienen KeyStorageFlags establecido en Exportable por defualt.
  • Intentar usar diferentes KeyStorageFlags resultará en una excepción => Internal.Cryptography.CryptoThrowHelper.WindowsCryptographicException: 'La operación solicitada no está soportada'.
:path=/static-assets/pdf/content-code-examples/how-to/signing-X509Certificate2-with-privatekey.cs
using IronPdf;
using IronPdf.Signing;
using System.Security.Cryptography.X509Certificates;

ChromePdfRenderer renderer = new ChromePdfRenderer();
PdfDocument pdf = renderer.RenderHtmlAsPdf("<h1>foo</h1>");

//  Crear objeto X509Certificate2 con X509KeyStorageFlags establecido a Exportable
X509Certificate2 cert = new X509Certificate2("IronSoftware.pfx", "123456", X509KeyStorageFlags.Exportable);

//  Crear objeto PdfSignature
var sig = new PdfSignature(cert);

//  Firmar documento PDF
pdf.Sign(sig);

pdf.SaveAs("signed.pdf");
Imports IronPdf
Imports IronPdf.Signing
Imports System.Security.Cryptography.X509Certificates

Private renderer As New ChromePdfRenderer()
Private pdf As PdfDocument = renderer.RenderHtmlAsPdf("<h1>foo</h1>")

'  Crear objeto X509Certificate2 con X509KeyStorageFlags establecido a Exportable
Private cert As New X509Certificate2("IronSoftware.pfx", "123456", X509KeyStorageFlags.Exportable)

'  Crear objeto PdfSignature
Private sig = New PdfSignature(cert)

'  Firmar documento PDF
pdf.Sign(sig)

pdf.SaveAs("signed.pdf")
VB   C#

Sign: Añadir detalles granulares a PdfSignature

Al instanciar PdfSignature o una vez instanciado, se puede añadir información útil al objeto PdfSignature, incluida la fecha, el contacto de firma, la ubicación, el motivo de la firma, el timestampe y la adición de una imagen como apariencia visual en el documento PDF.

Consejo
Compatible con servidores de sellado de tiempo que requieren SHA256 y SHA512

:path=/static-assets/pdf/content-code-examples/how-to/signing-add-granular-information.cs
using IronPdf;
using IronPdf.Signing;
using IronSoftware.Drawing;
using System;

ChromePdfRenderer renderer = new ChromePdfRenderer();
PdfDocument pdf = renderer.RenderHtmlAsPdf("<h1>foo</h1>");

pdf.SaveAs("signed.pdf");

//  Crear objeto PdfSignature
var sig = new PdfSignature("IronSoftware.pfx", "123456");

//  Añadir información granular
sig.SignatureDate = new DateTime(2000, 12, 02);
sig.SigningContact = "IronSoftware";
sig.SigningLocation = "Chicago";
sig.SigningReason = "How to guide";
sig.TimestampHashAlgorithm = TimestampHashAlgorithms.SHA256;
sig.TimeStampUrl = "http://timestamp.digicert.com";
sig.SignatureImage = new PdfSignatureImage("IronSoftware.png", 0, new Rectangle(0, 600, 100, 100));

//  Firmar y guardar documento PDF
sig.SignPdfFile("signed.pdf");
Imports IronPdf
Imports IronPdf.Signing
Imports IronSoftware.Drawing
Imports System

Private renderer As New ChromePdfRenderer()
Private pdf As PdfDocument = renderer.RenderHtmlAsPdf("<h1>foo</h1>")

pdf.SaveAs("signed.pdf")

'  Crear objeto PdfSignature
Dim sig = New PdfSignature("IronSoftware.pfx", "123456")

'  Añadir información granular
sig.SignatureDate = New DateTime(2000, 12, 02)
sig.SigningContact = "IronSoftware"
sig.SigningLocation = "Chicago"
sig.SigningReason = "How to guide"
sig.TimestampHashAlgorithm = TimestampHashAlgorithms.SHA256
sig.TimeStampUrl = "http://timestamp.digicert.com"
sig.SignatureImage = New PdfSignatureImage("IronSoftware.png", 0, New Rectangle(0, 600, 100, 100))

'  Firmar y guardar documento PDF
sig.SignPdfFile("signed.pdf")
VB   C#

Demostración

Ver detalles del firmante

Es posible que aparezca un signo de exclamación o de advertencia en lugar de una marca de verificación. Esto ocurre porque Adobe no puede confirmar la autenticidad e integridad del documento al no estar presente el certificado. Para obtener la marca de verificación, añada el certificado a Adobe y vuelva a abrir el documento.

Diferentes formas de añadir imágenes

Establece la propiedad SignatureImage a un nuevo objeto PdfSignatureImage.

:path=/static-assets/pdf/content-code-examples/how-to/signing-add-image-by-property.cs
using IronPdf.Signing;
using IronSoftware.Drawing;

//  Crear objeto PdfSignature
var sig = new PdfSignature("IronSoftware.pfx", "123456");

sig.SignatureImage = new PdfSignatureImage("IronSoftware.png", 0, new Rectangle(0, 600, 100, 100));
Imports IronPdf.Signing
Imports IronSoftware.Drawing

'  Crear objeto PdfSignature
Private sig = New PdfSignature("IronSoftware.pfx", "123456")

sig.SignatureImage = New PdfSignatureImage("IronSoftware.png", 0, New Rectangle(0, 600, 100, 100))
VB   C#

Utilice el método LoadSignatureImageFromFile para cargar una imagen desde un archivo. LoadSignatureImageFromFile admite varios formatos de imagen.

:path=/static-assets/pdf/content-code-examples/how-to/signing-add-image-from-file.cs
using IronPdf.Signing;
using IronSoftware.Drawing;

//  Crear objeto PdfSignature
var sig = new PdfSignature("IronSoftware.pfx", "123456");

sig.LoadSignatureImageFromFile("IronSoftware.png", 0, new Rectangle(0, 600, 100, 100));
Imports IronPdf.Signing
Imports IronSoftware.Drawing

'  Crear objeto PdfSignature
Private sig = New PdfSignature("IronSoftware.pfx", "123456")

sig.LoadSignatureImageFromFile("IronSoftware.png", 0, New Rectangle(0, 600, 100, 100))
VB   C#

Utilice el método LoadSignatureImageFromStream para cargar la imagen desde el flujo. El flujo de imágenes puede generarse a partir de otra biblioteca siempre que tenga el formato de TGA, PBM, TIFF , BMP, GIF, PNG,JPEG, Webp.

:path=/static-assets/pdf/content-code-examples/how-to/signing-add-image-from-stream.cs
using IronPdf.Signing;
using IronSoftware.Drawing;

//  Crear objeto PdfSignature
var sig = new PdfSignature("IronSoftware.pfx", "123456");

//  Importar imagen usando IronSoftware.Drawing
AnyBitmap image = AnyBitmap.FromFile("IronSoftware.png");

sig.LoadSignatureImageFromStream(image.ToStream(), 0, new Rectangle(0, 600, 100, 100));
Imports IronPdf.Signing
Imports IronSoftware.Drawing

'  Crear objeto PdfSignature
Private sig = New PdfSignature("IronSoftware.pfx", "123456")

'  Importar imagen usando IronSoftware.Drawing
Private image As AnyBitmap = AnyBitmap.FromFile("IronSoftware.png")

sig.LoadSignatureImageFromStream(image.ToStream(), 0, New Rectangle(0, 600, 100, 100))
VB   C#

Permisos de firma

Si lo desea, puede especificar explícitamente las condiciones en las que su Certificado seguirá siendo válido. Si desea que su Firma sea invalidada tras un cambio, o que sólo permita cambios en los campos del formulario, etc. Utilice la siguiente tabla para ver las opciones:

PdfDocument.SignaturePermissionsDefinición
NoChangesAllowedNo se permiten cambios
FormFillingAllowedSe permite cambiar los valores de los campos del formulario
FormFillingAndAnnotationsAllowedSe permite cambiar los valores de los campos del formulario y modificar las anotaciones

Este parámetro es opcional y si no se establece se aplicará una firma que certifica una revisión específica y no puede ser invalidada.

Guardar y firmar una iteración de revisión en PDF

En el siguiente ejemplo abrimos un archivo PDF, realizamos varias ediciones y, antes de guardarlo, lo firmamos. Para los permisos de firma, sólo permitiremos rellenar formularios como futuras ediciones, de lo contrario la firma quedará invalidada de cualquier otra edición.

A continuación, llamaremos a SaveAsRevision para guardar la revisión en el historial y luego guardar nuestro nuevo documento en el disco.

:path=/static-assets/pdf/content-code-examples/how-to/signing-revision.cs
using IronPdf;
using IronPdf.Rendering;

//  Importar PDF y activar TrackChanges
PdfDocument pdf = PdfDocument.FromFile("annual_census.pdf", TrackChanges: ChangeTrackingModes.EnableChangeTracking);
//  ... varias ediciones ...
pdf.SignWithFile("/assets/IronSignature.p12", "password", null, IronPdf.Signing.SignaturePermissions.FormFillingAllowed);

PdfDocument pdfWithRevision = pdf.SaveAsRevision();

pdfWithRevision.SaveAs("annual_census_2.pdf");
Imports IronPdf
Imports IronPdf.Rendering

'  Importar PDF y activar TrackChanges
Private pdf As PdfDocument = PdfDocument.FromFile("annual_census.pdf", TrackChanges:= ChangeTrackingModes.EnableChangeTracking)
'  ... varias ediciones ...
pdf.SignWithFile("/assets/IronSignature.p12", "password", Nothing, IronPdf.Signing.SignaturePermissions.FormFillingAllowed)

Dim pdfWithRevision As PdfDocument = pdf.SaveAsRevision()

pdfWithRevision.SaveAs("annual_census_2.pdf")
VB   C#

Comprender el ahorro incremental para las firmas

Mientras que algunos visores, como el navegador Chrome, sólo muestran una versión, los archivos PDF tienen la capacidad de almacenar versiones anteriores del documento, de forma similar al historial de commits de Git. Lo verá en visores de PDF más avanzados, como Adobe Acrobat.

Cuando se trata de firmas de PDF, es importante saber esto porque la acción de firmar un PDF se aplica a la iteración actual del PDF. Su PDF puede tener firmas de iteraciones anteriores, o puede tener algunas versiones sin firmar. Podemos visualizar un ejemplo como el siguiente:

Iteración de documentos PDFCertificado ACertificado BCertificado CCertificado D
0 (primera parada)
1
2
3
(sólo edición de campos de formulario)

(sólo edición de campos de formulario)
4 (sólo campos de formulario editados)
5
(no se permiten más ediciones)

(no se permiten más ediciones)

(no se permiten más ediciones)

Arriba tenemos un documento que ha pasado por 6 iteraciones diferentes. Este documento puede estar pasando por los departamentos de una empresa con aprobación hasta ser finalizado en la iteración 3. En esta iteración, tanto la Persona A como la Persona B firmaron el documento con el permiso "Sólo edición de campos de formulario". Esto significa que se permite rellenar los campos del formulario en el documento PDF, pero cualquier otro cambio en el documento invalidará sus firmas.

En el ejemplo anterior, podemos suponer que la Persona C es la que ha rellenado el formulario y lo ha devuelto a las Personas A, C y D, que han firmado el documento por última vez con el permiso "No se permiten modificaciones". Dado que en este documento no se han realizado acciones ilegales que invaliden las firmas, cuando ejecutemos el método de firma de IronPDF obtendremos true.

Volver a una revisión anterior

Para volver a una revisión anterior de un PDF, puede utilizar el método GetRevision. Esto olvidará cualquier cambio realizado desde esta revisión, incluidas las firmas más recientes. Para ello, utilice:

:path=/static-assets/pdf/content-code-examples/how-to/signing-revert-revision.cs
using IronPdf;

PdfDocument pdf = PdfDocument.FromFile("report.pdf");

int versions = pdf.RevisionCount; //  revisiones totales

PdfDocument rolledBackPdf = pdf.GetRevision(2);
rolledBackPdf.SaveAs("report-draft.pdf");
Imports IronPdf

Private pdf As PdfDocument = PdfDocument.FromFile("report.pdf")

Private versions As Integer = pdf.RevisionCount '  revisiones totales

Private rolledBackPdf As PdfDocument = pdf.GetRevision(2)
rolledBackPdf.SaveAs("report-draft.pdf")
VB   C#

Eliminar firmas

IronPDF tiene un método RemoveSignatures que eliminará todas las firmas de todas las revisiones de un documento PDF. El uso es el siguiente:

:path=/static-assets/pdf/content-code-examples/how-to/signing-remove-signature.cs
using IronPdf;

PdfDocument pdf = PdfDocument.FromFile("invoice.pdf");
pdf.RemoveSignatures();
Imports IronPdf

Private pdf As PdfDocument = PdfDocument.FromFile("invoice.pdf")
pdf.RemoveSignatures()
VB   C#

Verificar todas las firmas de un PDF

Al llamar al método de verificación de firmas en un documento PDF, se examinarán todas las firmas de todas las iteraciones del documento y se comprobará que siguen siendo válidas. Esto devolverá un bool de true si todos son válidos.

:path=/static-assets/pdf/content-code-examples/how-to/signing-verify-signatures.cs
using IronPdf;

PdfDocument pdf = PdfDocument.FromFile("annual_census.pdf");
bool isValid = pdf.VerifyPdfSignatures();
Imports IronPdf

Private pdf As PdfDocument = PdfDocument.FromFile("annual_census.pdf")
Private isValid As Boolean = pdf.VerifyPdfSignatures()
VB   C#

Estampar una firma en un PDF

En primer lugar, empezaré con un PDF que quiero firmar. Utilizaré esta factura de ejemplo:

Aplicaremos una firma manuscrita en forma de imagen .png a nuestro PDF. Puede ser una firma manuscrita o la imagen que se utilizó en la creación de un archivo de certificado. Este es el ejemplo de firma que utilizaremos:

Código

Con esto usaremos el siguiente código para estampar la firma manuscrita al PDF como marca de agua:

:path=/static-assets/pdf/content-code-examples/how-to/signing-handwritten.cs
using IronPdf;
using IronPdf.Editing;

var pdf = PdfDocument.FromFile("invoice.pdf");

pdf.ApplyWatermark("<img src='signature.png'/>", 90, VerticalAlignment.Bottom, HorizontalAlignment.Right);

pdf.SaveAs("official_invoice.pdf");
Imports IronPdf
Imports IronPdf.Editing

Private pdf = PdfDocument.FromFile("invoice.pdf")

pdf.ApplyWatermark("<img src='signature.png'/>", 90, VerticalAlignment.Bottom, HorizontalAlignment.Right)

pdf.SaveAs("official_invoice.pdf")
VB   C#

Salida Resultado

Después de ejecutar este código, tenemos este archivo de salida que tiene nuestra firma en la parte inferior derecha:

Añadir un campo de firma sin firmar a un PDF

Esta opción aún no está disponible. Puede obtener más información sobre IronPDF y los formularios que admite en la página Rellenar formularios PDF mediante programación en C# artículo.