Compartir a través de


Firmas criptográficas

Las firmas digitales criptográficas utilizan algoritmos de clave pública para proporcionar integridad de datos. Al firmar datos con una firma digital, otra persona puede comprobar la firma y probar que los datos provienen del usuario y que no se han modificado después de ser firmados. Para obtener más información sobre firmas digitales, vea Servicios criptográficos.

En este tema, se explica cómo generar y comprobar firmas digitales mediante clases del espacio de nombres System.Security.Cryptography.

  • Generar firmas

  • Comprobar firmas

Generar firmas

Las firmas digitales se suelen aplicar a valores hash que representan datos mayores. En el ejemplo siguiente se aplica una firma digital a un valor hash. En primer lugar, se crea una nueva instancia de la clase RSACryptoServiceProvider para generar un par de claves pública y privada. A continuación, se pasa RSACryptoServiceProvider a una nueva instancia de la clase RSAPKCS1SignatureFormatter. De esta forma, se transfiere la clave privada a RSAPKCS1SignatureFormatter, que realiza la firma digital. Para firmar el código hash, debe especificar el algoritmo hash que se utilizará. En este ejemplo se utiliza el algoritmo SHA1. Por último, se llama al método RSAPKCS1SignatureFormatter.CreateSignature para realizar la firma.

Imports System
Imports System.Security.Cryptography

Module Module1
    Sub Main()
        'The hash value to sign.
        Dim HashValue As Byte() = {59, 4, 248, 102, 77, 97, 142, 201, 210, 12, 224, 93, 25, 41, 100, 197, 213, 134, 130, 135}

        'The value to hold the signed value.
        Dim SignedHashValue() As Byte

        'Generate a public/private key pair.
        Dim RSA As New RSACryptoServiceProvider()

        'Create an RSAPKCS1SignatureFormatter object and pass it 
        'the RSACryptoServiceProvider to transfer the private key.
        Dim RSAFormatter As New RSAPKCS1SignatureFormatter(RSA)

        'Set the hash algorithm to SHA1.
        RSAFormatter.SetHashAlgorithm("SHA1")

        'Create a signature for HashValue and assign it to 
        'SignedHashValue.
        SignedHashValue = RSAFormatter.CreateSignature(HashValue)
    End Sub
End Module

using System;
using System.Security.Cryptography;
class Class1
{
   static void Main()
   {
      //The hash value to sign.
      byte[] HashValue = {59,4,248,102,77,97,142,201,210,12,224,93,25,41,100,197,213,134,130,135};

      //The value to hold the signed value.
      byte[] SignedHashValue;

      //Generate a public/private key pair.
      RSACryptoServiceProvider RSA = new RSACryptoServiceProvider();

      //Create an RSAPKCS1SignatureFormatter object and pass it the 
      //RSACryptoServiceProvider to transfer the private key.
      RSAPKCS1SignatureFormatter RSAFormatter = new RSAPKCS1SignatureFormatter(RSA);

      //Set the hash algorithm to SHA1.
      RSAFormatter.SetHashAlgorithm("SHA1");

      //Create a signature for HashValue and assign it to 
      //SignedHashValue.
      SignedHashValue = RSAFormatter.CreateSignature(HashValue);
   }
}

Firmar archivos XML

.NET Framework proporciona el espacio de nombres System.Security.Cryptography.XML, que permite firmar archivos XML. La firma de XML es importante cuando se desea comprobar que el XML se origina en cierta fuente. Por ejemplo, si utiliza un servicio de cotización en bolsa que utiliza XML, puede comprobar el origen del XML si está firmado.

Las clases de este espacio de nombres siguen la recomendación XML-Signature Syntax and Processing de World Wide Web Consortium.

Volver al principio

Comprobar firmas

Para comprobar que alguien en concreto firmó los datos, debe disponer de la información siguiente:

  • La clave pública del firmante de los datos.

  • La firma digital.

  • Los datos firmados.

  • El algoritmo hash que utilizó el firmante.

Para comprobar una firma realizada por la clase RSAPKCS1SignatureFormatter, utilice la clase RSAPKCS1SignatureDeformatter. La clase RSAPKCS1SignatureDeformatter debe recibir la clave pública del firmante. Necesitará los valores del módulo y el exponente para especificar la clave pública. (La parte que generó el par de claves pública y privada debe proporcionar estos valores.) Primero, debe crear un objeto RSACryptoServiceProvider para contener la clave pública que comprobará la firma y, después, debe inicializar una estructura RSAParameters con los valores del módulo y del exponente que especifican la clave pública.

En el código siguiente se muestra la creación de una estructura RSAParameters. La propiedad Modulus se establece en el valor de una matriz de bytes denominada ModulusData y la propiedad Exponent se establece en el valor de una matriz de bytes denominada ExponentData.

Dim RSAKeyInfo As RSAParameters
RSAKeyInfo.Modulus = ModulusData
RSAKeyInfo.Exponent = ExponentData
RSAParameters RSAKeyInfo;
RSAKeyInfo.Modulus = ModulusData;
RSAKeyInfo.Exponent = ExponentData;

Después de crear el objeto RSAParameters, puede inicializar una nueva instancia de la clase RSACryptoServiceProvider con los valores especificados en RSAParameters. RSACryptoServiceProvider, a su vez, se pasa al constructor de RSAPKCS1SignatureDeformatter para transferir la clave.

En el ejemplo siguiente se muestra este proceso. En este ejemplo, HashValue y SignedHashValue son matrices de bytes que proporciona una parte remota. La parte remota ha firmado HashValue mediante el algoritmo SHA1, por lo que ha generado la firma digital SignedHashValue. El

RSAPKCS1SignatureDeformatter.VerifySignature comprueba si la firma digital es válida y se usó para firmar HashValue.

Dim RSA As New RSACryptoServiceProvider()
RSA.ImportParameters(RSAKeyInfo)
Dim RSADeformatter As New RSAPKCS1SignatureDeformatter(RSA)
RSADeformatter.SetHashAlgorithm("SHA1")
If RSADeformatter.VerifySignature(HashValue, SignedHashValue) Then
   Console.WriteLine("The signature is valid.")
Else
   Console.WriteLine("The signture is not valid.")
End If
RSACryptoServiceProvider RSA = new RSACryptoServiceProvider();
RSA.ImportParameters(RSAKeyInfo);
RSAPKCS1SignatureDeformatter RSADeformatter = new RSAPKCS1SignatureDeformatter(RSA);
RSADeformatter.SetHashAlgorithm("SHA1");
if(RSADeformatter.VerifySignature(HashValue, SignedHashValue))
{
   Console.WriteLine("The signature is valid.");
}
else
{
   Console.WriteLine("The signature is not valid.");
}

Este fragmento de código mostrará "The signature is valid" si la firma es válida, y "The signature is not valid" si no lo es.

Volver al principio

Vea también

Conceptos

Servicios criptográficos

Otros recursos

Tareas criptográficas