Esta página puede contener texto traducido automáticamente.
Cómo firmar PDF con tokens USB y dispositivos HSM en C# y VB.NET
Las autoridades de certificación de confianza ya no permiten la descarga de claves privadas para certificados de firma de documentos. En su lugar, estas deben almacenarse en hardware seguro, como tokens USB, tarjetas inteligentes o HSM en la nube.
Puede usar la biblioteca Docotic.Pdf para firmar documentos PDF en .NET mediante dispositivos HSM. Este artículo describe las integraciones con Azure Key Vault, AWS KMS y hardware compatible con PKCS#11.
9.7.18373 15,244 pasaron Descargas totales de NuGet 5,976,723Puede obtener la biblioteca y una clave de licencia gratuita por tiempo limitado en la página Descargar la biblioteca PDF de C# .NET.
Prerrequisitos
Los ejemplos de código de este artículo utilizan certificados autofirmados para firmar documentos PDF. Por defecto, los visores de PDF no confían en estas firmas. Los certificados autofirmados deben usarse solo para pruebas, no en entornos de producción. Para generar firmas PDF confiables, utilice certificados de firma de documentos emitidos por autoridades de certificación externas.
Obtenga el certificado correcto
Prefiera certificados de empresas incluidas en la Lista de Confianza Aprobada de Adobe (AATL). Adobe Acrobat confía en los certificados de dichas empresas por defecto y no mostrará la advertencia "Se desconoce la validez del certificado".
Para crear documentos que cumplan con la normativa eIDAS de la UE, necesita utilizar certificados cualificados emitidos por proveedores incluidos en las Listas de Confianza de la Unión Europea (EUTL).
Aprenda a usar su certificado en .NET
Al solicitar un certificado de firma de documentos, normalmente recibirá acceso a un dispositivo HSM. Este puede ser un token USB físico o una solución HSM en la nube.
Entonces debería aprender a firmar datos con este HSM. Esta suele ser la parte más complicada, ya que cada proveedor de cifrado es diferente. Debe consultar la documentación de su token USB o API en la nube.
Idealmente, necesita encontrar un SDK .NET correspondiente. O al menos encontrar un SDK nativo y usarlo mediante interoperabilidad en .NET.
Su objetivo es obtener código C# o VB.NET que pueda firmar cualquier byte con su certificado.
PDF API para firma externa
Una vez que pueda firmar cualquier byte con su dispositivo HSM, estará listo para firmar documentos PDF con Docotic.Pdf. Para ello, implemente la interfaz IPdfSigner y úsela para firmar.
Implementar la interfaz IPdfSigner
IPdfSigner
declara dos miembros. La propiedad SignatureAlgorithm
devuelve el algoritmo
utilizado para la firma. Normalmente, se utilizan algoritmos RSA o ECDSA.
El método Sign
es la parte clave del flujo de firma externa. Docotic.Pdf proporciona el resumen
de los bytes de un documento PDF a este método. Debe firmar este resumen con su dispositivo HSM y
devolver los bytes de una firma digital. Tenga en cuenta que no debe devolver un objeto PKCS#7.
Simplemente genere y devuelva la firma criptográfica.
Docotic.Pdf llama al método Sign
dos veces por cada firma. La primera llamada calcula el espacio
necesario para la firma. La segunda, la firma del documento.
Crear PdfSigningOptions para firma externa
Utilice el
constructor PdfSigningOptions(IPdfSigner, X509Certificate2[])
para firmar documentos PDF con su implementación de IPdfSigner
. Obtenga una cadena de
certificados y proporciónela como segundo argumento. Se requiere al menos un certificado, y el
certificado de firma debe ir primero.
La última pieza del rompecabezas es la propiedad PdfSigningOptions.DigestAlgorithm
. El valor de
esta propiedad debe coincidir con IPdfSigner.SignatureAlgorithm
y con la implementación de
IPdfSigner.Sign
.
Repasemos cómo firmar PDF con firmas externas en situaciones comunes.
Firmar documentos PDF con el controlador PKCS#11 en C#
Si su token USB criptográfico o tarjeta inteligente incluye un controlador PKCS#11, puede usar las bibliotecas Pkcs11Interop.X509Store o Pkcs11Interop en .NET. ``Pkcs11Interop` es compatible con tarjetas inteligentes Atos CardOS, YubiKey PIV, SmartCard-HSM, SafeNet ProtectServer HSM y otros HSM.
El ejemplo de código Firmar documentos PDF utilizando los controladores PKCS#11 muestra cómo firmar documentos PDF con un token USB o una tarjeta inteligente. Deberá personalizar estas líneas:
string pkcsLibraryPath = @"C:\Program Files\SoftHSM2\lib\softhsm2-x64.dll";
ulong slotId = 1743347971;
string alias = "YOUR-ALIAS";
string certLabel = "YOUR-CERTIFICATE";
string pin = "YOUR-PIN";
var digestAlgorithm = PdfDigestAlgorithm.Sha512;
Nuestra configuración de ejemplo utiliza SoftHSM2 como emulador de un token USB. En aplicaciones reales, no necesita SoftHSM2. En su lugar, utilice el controlador que viene con el token USB.
Firmar documentos PDF con Azure Key Vault
Microsoft Azure Key Vault almacena de forma segura certificados y claves. Deberá realizar los siguientes preparativos:
- Crear una cuenta de Azure.
- Crear un usuario de Azure.
- Crear un Key Vault.
- Permitir el acceso a Key Vault al usuario de Azure seleccionado.
- Agregar un certificado de firma de documentos a Key Vault. Puede importar certificados de entidades de certificación integradas.
A continuación, use el paquete NuGet Azure.Security.KeyVault.Keys
para iniciar sesión en .NET.
Ejemplo de código C# para firmar con una clave de Azure Key Vault:
var vaultUrl = new Uri("https://YOUR-VAULT.vault.azure.net/");
var credential = new DefaultAzureCredential();
var keyClient = new KeyClient(vaultUrl, credential);
KeyVaultKey key = keyClient.GetKey("YOUR-KEY");
var cryptoClient = new CryptographyClient(key.Id, credentials);
byte[] messageToSign = ..;
byte[] signature = cryptoClient.SignData(SignatureAlgorithm.RS512, messageToSign).Signature;
Una implementación de IPdfSigner
relacionada podría verse así:
class AzureSigner : IPdfSigner
{
private readonly CryptographyClient m_client;
private readonly AzureSignatureAlgorithm m_signingAlgorithm;
public AzureSigner(CryptographyClient client, AzureSignatureAlgorithm signingAlgorithm)
{
m_client = client;
m_signingAlgorithm = signingAlgorithm;
}
public PdfSignatureAlgorithm SignatureAlgorithm
{
get
{
if (m_signingAlgorithm == AzureSignatureAlgorithm.RS256 ||
m_signingAlgorithm == AzureSignatureAlgorithm.RS384 ||
m_signingAlgorithm == AzureSignatureAlgorithm.RS512)
return PdfSignatureAlgorithm.Rsa;
throw new NotSupportedException($"Unsupported {nameof(SignatureAlgorithm)} value: {m_signingAlgorithm}");
}
}
public PdfDigestAlgorithm DigestAlgorithm
{
get
{
if (m_signingAlgorithm == AzureSignatureAlgorithm.RS256)
return PdfDigestAlgorithm.Sha256;
if (m_signingAlgorithm == AzureSignatureAlgorithm.RS384)
return PdfDigestAlgorithm.Sha384;
if (m_signingAlgorithm == AzureSignatureAlgorithm.RS512)
return PdfDigestAlgorithm.Sha512;
throw new NotSupportedException($"Unsupported {nameof(SignatureAlgorithm)} value: {m_signingAlgorithm}");
}
}
public byte[] Sign(byte[] message)
{
return m_client.SignData(m_signingAlgorithm, message).Signature;
}
}
Finalmente, use esta clase AzureSigner
para firmar documentos PDF:
CryptographyClient cryptoClient = ..;
using X509Certificate2 cert = ..
var signer = new AzureSigner(cryptoClient, SignatureAlgorithm.RS512);
using var pdf = new PdfDocument();
PdfPage page = pdf.Pages[0];
PdfSignatureField field = page.AddSignatureField(50, 50, 200, 200);
var options = new PdfSigningOptions(signer, new[] { cert })
{
DigestAlgorithm = signer.DigestAlgorithm,
Field = field,
};
pdf.SignAndSave(options, ..);
Explore el ejemplo de código completo de Firmar documentos PDF con Azure Key Vault en GitHub.
Firmar documentos PDF con AWS KMS
AWS Key Management Service (KMS) es otro almacenamiento seguro para claves criptográficas. La preparación sigue los mismos pasos que en Azure Key Vault:
- Cree una cuenta de AWS.
- Cree un usuario de IAM.
- Agregue una clave de firma.
- Permita el acceso a las claves al usuario de IAM seleccionado.
Para AWS, necesitará usar el paquete NuGet AWSSDK.KeyManagementService
en .NET. El código de
ejemplo para la firma de PDF es bastante similar al escenario de Azure:
using var pdf = new PdfDocument();
PdfPage page = pdf.Pages[0];
PdfSignatureField field = page.AddSignatureField(50, 50, 200, 200);
var signingAlgorithm = SigningAlgorithmSpec.RSASSA_PSS_SHA_512;
var signer = new AwsSigner("arn:aws:kms:YOUR-id", signingAlgorithm)
var options = new PdfSigningOptions(signer, new[] { cert })
{
DigestAlgorithm = signer.DigestAlgorithm,
Field = field,
};
pdf.SignAndSave(options, ..);
class AwsSigner : IPdfSigner
{
private readonly string m_keyId;
private readonly SigningAlgorithmSpec m_signingAlgorithm;
public AwsSigner(string keyId, SigningAlgorithmSpec signingAlgorithm)
{
m_keyId = keyId;
m_signingAlgorithm = signingAlgorithm;
}
public PdfSignatureAlgorithm SignatureAlgorithm
{
get
{
if (m_signingAlgorithm == SigningAlgorithmSpec.RSASSA_PKCS1_V1_5_SHA_256 ||
m_signingAlgorithm == SigningAlgorithmSpec.RSASSA_PKCS1_V1_5_SHA_384 ||
m_signingAlgorithm == SigningAlgorithmSpec.RSASSA_PKCS1_V1_5_SHA_512)
return PdfSignatureAlgorithm.Rsa;
throw new NotSupportedException($"Unsupported {nameof(SigningAlgorithmSpec)} value: {m_signingAlgorithm}");
}
}
public PdfDigestAlgorithm DigestAlgorithm
{
get
{
string alg = m_signingAlgorithm.Value;
if (alg.EndsWith("256"))
return PdfDigestAlgorithm.Sha256;
if (alg.EndsWith("384"))
return PdfDigestAlgorithm.Sha384;
if (alg.EndsWith("512"))
return PdfDigestAlgorithm.Sha512;
throw new NotSupportedException($"Unsupported {nameof(SigningAlgorithmSpec)} value: {m_signingAlgorithm}");
}
}
public byte[] Sign(byte[] message)
{
using var kmsClient = new AmazonKeyManagementServiceClient();
using var stream = new MemoryStream(message);
var signRequest = new SignRequest()
{
SigningAlgorithm = m_signingAlgorithm,
KeyId = m_keyId,
MessageType = MessageType.RAW,
Message = stream,
};
SignResponse signResponse = kmsClient.SignAsync(signRequest).GetAwaiter().GetResult();
return signResponse.Signature.ToArray();
}
}
El ejemplo de código completo Firmar documentos PDF con AWS KMS también está disponible en GitHub.
Conclusión
Utilice la biblioteca Docotic.Pdf para firmar documentos PDF con tokens USB, tarjetas
inteligentes o HSM en la nube. Para ello, implemente la interfaz IPdfSigner
en código C# o VB.NET.
Descarga y prueba ejemplos de código para firmas digitales en PDF desde GitHub. Consulta artículos relacionados para obtener más información:
Preguntas frecuentes
¿Cómo firmo un PDF con un token USB o una tarjeta inteligente?
Utilice las bibliotecas Docotic.Pdf y Pkcs11Interop .NET para firmar archivos PDF con token o tarjeta inteligente. Consulte la sección Firmar documentos PDF con el controlador PKCS#11 en C# para obtener más información.
¿Cómo uso SoftHSM con mi token USB o tarjeta inteligente?
SoftHSM simula un dispositivo HSM real. No necesita SoftHSM si tiene un token USB o una tarjeta inteligente. En su lugar, use el controlador PKCS#11 incluido con su dispositivo HSM.
¿Cómo firmo un documento PDF con una firma externa?
Consulta las secciones Firmar documentos PDF con Azure Key Vault y Firmar documentos PDF con AWS KMS. La firma externa de PDF con otros HSM en la nube sigue un proceso similar.
¿Cómo uso Azure Key Vault en .NET?
Utilice el paquete NuGet Azure.Security.KeyVault.Keys
. Pruebe el ejemplo de código
Firmar documentos PDF con Azure Key Vault de GitHub.