Joven hacker sonriendo

Hackeamos su software

cero falsos positivos

Inteligencia experta + Tecnología especializada
DXST - SAST - IAST - SCA - DevSecOps
Caja blanca - Caja gris - Caja negra
Atacando Aplicaciones Web, APIs, Apps Móviles,
Cliente Servidor, Servidores, Redes, Dispositivos IoT
IoT SCI: Sistemas de Control Industrial

Firmar datos con RSA y SHA256

Nuestros ethical hackers explican cómo evitar vulnerabilidades de seguridad mediante la programación segura en ASPNET al firmar datos con RSA y SHA256. Las firmas digitales permiten verificar la autenticidad de los datos permitiéndoles cumplir con el principio de integridad y no repudio.

Necesidad

Firma de datos con RSA y SHA256 en ASP.Net.

Contexto

A continuación se describen las circunstancias bajo las cuales la siguiente solución tiene sentido:

  1. Se está desarrollando una aplicación en ASP.Net.

  2. Se desea firmar contenido.[1]

Solución

Las firmas digitales, al igual que las firmas hechas a puño y letra, sirven para autentificar la identidad de su autor, otorgar un consentimiento, o aprobar la información contenida en un documento con validez legal.

Las firmas digitales se realizan a través de un proceso criptográfico el cual debe cumplir con los principios de autenticación, integridad y no repudio. Además, una firma digital debe ser:

  • Única: Generada por un único firmante.

  • Infalsificable: Computacionalmente segura.

  • Verificable: Puede ser corroborada por jueces o autoridades competentes.

  • Innegable: El firmante no puede negar su propia firma.

  • Viable: Fácil de generar.

En ASP.NET es posible generar firmas digitales utilizando criptografía asimétrica RSA o funciones hash criptográficas como SHA256. Para ello, se realizan los siguientes pasos:

  1. El primer ítem necesario es el certificado con la respectiva clave privada. Una posibilidad es leer el certificado de la máquina local o el usuario actual usando un archivo .cer que permita identificar la clave privada, para luego enumerar los certificados y el hash correspondiente [2]. A continuación se presenta una porción de código con el procedimiento anteriormente descrito:

    Certificates.java
    1
    2
    3
    4
    5
    6
    7
    8
    9
    X509Certificate2 publicCert = new X509Certificate2(@"C:\mycertificate.cer");
    X509Certificate2 privateCert = null;
    X509Store store = new X509Store(StoreLocation.LocalMachine);
    store.Open(OpenFlags.ReadOnly);
    foreach( X509Certificate2 cert in store.Certificates)
    {
        if (cert.GetCertHashString() == publicCert.GetCertHashString())
            privateCert = cert;
    }
    
  2. Sin importar la forma en que se obtenga el certificado con la clave privada, en algunos casos se requiere reconstruirlo. La razón por la cual esto se hace necesario es para cambiar el CSP (proveedor de servicios de criptografía), ya que se va a usar SHA256 el cual es más seguro que otros hash que han demostrado tener problemas de colisiones [3]. Lo primero que se hace es exportar la clave y luego reimportarla usando cualquier formato intermedio, en esta solución se usa XML.

    1
    2
    RSACryptoServiceProvider key = new RSACryptoServiceProvider();
    key.FromXmlString(privateCert.PrivateKey.ToXmlString(true));
    
  3. Una vez que se tiene esto listo, se procede a firmar los datos. Pero antes, se necesitan datos que firmar.

    1
    byte[] data = new byte[1024];
    
  4. Y se procede a realizar su firma:

    1
    byte[] sig = key.SignData(data, CryptoConfig.MapNameToOID("SHA256"));
    
  5. Finalmente, la verificación de la firma se hace usando el certificado digital, sin necesidad de hacer el proceso de exportar/importar o la clave privada.

    1
    2
    3
    key = (RSACryptoServiceProvider)publicCert.PublicKey.Key;
    if (!key.VerifyData(data, CryptoConfig.MapNameToOID("SHA256"), sig))
        throw new CryptographicException();
    



Haz un comentario

Estado de los servicios - Términos de Uso