Firmas digitales en C #

  • La firma electrónica es un conjunto de datos electrónicos que acompañan o que están asociados a un documento electrónico y cuyas funciones básicas son:
    • Identificar al firmante de manera inequívoca
    • Asegurar la integridad del documento firmado. Asegura que el documento firmado es exactamente el mismo que el original y que no ha sufrido alteración o manipulación.
    • Asegurar el no repudio del documento firmado. Los datos que utiliza el firmante para realizar la firma son únicos y exclusivos y, por tanto, posteriormente, no puede decir que no ha firmado el documento.
  • La firma digital es un sello que el usuario coloca en los datos que le son exclusivos y que es muy difícil de falsificar.

Uso de clave en firma digital

La firma digital se basa en un mecanismo de encriptación de clave pública o asimétrica.

  1. Clave privada: la persona que firma el documento digital, utiliza su clave privada para cifrar el hash del documento.
  2. Clave pública: En el proceso de verificación de la firma digital, quine recibe el documento y desea comprobar la firma de este, utiliza la clave pública de la persona que cifró el hash para descifrarlo y comprobar que corresponde con el hash del documento recibido..

Nota: Si los valores hash de la firma y la verificación son los mismos, entonces la firma es válida y la persona puede estar segura que la información no ha sido alterada desde que el remitente la firmó.

crear firma digital en #c

  1. El remitente aplica un algoritmo de hashing a los datos que se envían y crea un «resumen del mensaje» o HASH. El HASH es una representación compacta de los datos que se envían Y cada mensaje tiene un HASH único.
  2. El remitente encripta el HASH del mensaje con su clave privada para firmar digitalmente el mensaje.
  3. El remitente envía los datos a través de un canal seguro junto con su firma digital.
  4. El receptor recibe los datos y descifra la firma digital usando la clave pública del remitente y recupera el HASH del mensaje original.
  5. El receptor aplica el mismo algoritmo hash que el remitente de los datos para obtener el HASH del mensaje original y poder compararlo con el que ha obtenido de la firma.
  6. Si el HASH contenido en la firma del remitente y el HASH obtenido de aplicar el algoritmo al documento coinciden, significa que el mensaje realmente proviene de dicho remitente i no ha sido alterado.

Flujo de trabajo:

1. Prerrequisitos antes de firmar:

Se requiere: el pdf a firmar, cadena de certificados del lado del servidor, configurar la infraestructura de firma, extraer el HASH del mensaje y enviar este al cliente como una matriz de bytes

2. Para firmar:

Se requiere: HASH del mensaje como matriz de bytes, clave privada del lado del cliente, aplicar algoritmos criptográficos al HASH del mensaje para generar la firma y enviar esta  al servidor

3. Tras la firma:

Se requiere: la firma digital como matriz de bytes, el pdf original En el lado del servidor, inserte el resumen firmado
en la firma preparada, inserte la firma en el documento PDF

Componentes del Framework .net relacionados

.NET Framework proporciona clases RSACrypto Service Provider, RSAPKCS1 Signature Formatter y RSAPKCS1 Signature Deformatter que le permiten crear y verificar firmas digitales. Todas ellas residen en el espacio de nombres System.Security.Cryptography

Ejemplo (usando itextshap):

using iTextSharp.text.pdf;
using System;
using System.Collections.Generic;
using System.IO;
using System.Security.Cryptography.X509Certificates;
using Org.BouncyCastle.Security;
using Org.BouncyCastle.X509;
using X509Certificate = Org.BouncyCastle.X509.X509Certificate;
using iTextSharp.text.pdf.security;

Todas las referencias mencionadas anteriormente se utilizan para acceder a DSC, Firmar DSC, Leer PDF y Crear un nuevo PDF firmado.

Cree una variable para X509Certificate2 y obtenga todos los usuarios de DSC registrados en la local STORE y para el usuario actual que usa X509Store, PFB y luego X509Store «st» recopilará todos los certificados

X509Certificate2 certClient = null;
X509Store st = new X509Store(StoreName.My, StoreLocation.CurrentUser);
st.Open(OpenFlags.MaxAllowed);
X509Certificate2Collection collection = st.Certificates;

Código C #:

new Pkcs12Store(new FileStream(KEYSTORE, FileMode.Open), PASSWORD);
String alias = “”;
ICollection<X509Certificate> chain = new List<X509Certificate>();
// searching for private key
foreach (string al in store.Aliases)
if (store.IsKeyEntry(al) && store.GetKey(al).Key.IsPrivate) {
alias = al;
break;
}
AsymmetricKeyEntry pk = store.GetKey(alias);
foreach (X509CertificateEntry c in store.GetCertificateChain(alias))
chain.Add(c.Certificate);
RsaPrivateCrtKeyParameters parameters = pk.Key as RsaPrivateCrtKeyParameters;
PdfReader reader = newPdfReader(src);
FileStream os = newFileStream(dest, FileMode.Create);
PdfStamper stamper = PdfStamper.CreateSignature(reader, os, ‘\0’);
// Creating the appearance
PdfSignatureAppearance appearance = stamper.SignatureAppearance;
appearance.Reason = “Test signing”; appearance.Location = “test Location”;
appearance.SetVisibleSignature(newRectangle(36, 748, 144, 780), 1, “sig”);
// Creating the signature
IExternalSignature pks = newPrivateKeySignature(parameters, DigestAlgorithms.SHA256);
MakeSignature.SignDetached(appearance, pks, chain, null, null, null, 0, CryptoStandard.CMS);