Assinaturas criptográficas

As assinaturas digitais criptográficas usam algoritmos de chave pública para fornecer integridade de dados. Quando você assina dados com uma assinatura digital, outra pessoa pode verificar a assinatura e pode provar que os dados se originaram de você e não foram alterados depois que você os assinou. Para obter mais informações sobre assinaturas digitais, confira Serviços de criptografia.

Este tópico explica como gerar e verificar assinaturas digitais usando classes no namespace System.Security.Cryptography.

Gerar uma assinatura

Em geral, as assinaturas digitais são aplicadas a valores de hash que representam dados maiores. O exemplo a seguir aplica uma assinatura digital a um valor de hash. Primeiro, uma instância da classe RSA é criada para gerar um par de chaves pública/privada. Em seguida, o RSA é transmitido para uma nova instância da classe RSAPKCS1SignatureFormatter. Isso transfere a chave privada para o RSAPKCS1SignatureFormatter que, na verdade, executa a assinatura digital. Para assinar o código hash, você precisa especificar um algoritmo de hash a ser usado. Este exemplo usa o algoritmo SHA256. Por fim, o método CreateSignature é chamado para executar a assinatura.

Imports System.Security.Cryptography
Imports System.Text

Module Program
    Sub Main()

        Dim alg As SHA256 = SHA256.Create()

        Dim data As Byte() = Encoding.UTF8.GetBytes("Hello, from the .NET Docs!")
        Dim hash As Byte() = alg.ComputeHash(data)

        Dim sharedParameters As RSAParameters
        Dim signedHash As Byte()

        ' Generate signature
        Using rsa As RSA = RSA.Create()
            sharedParameters = rsa.ExportParameters(True)
            Dim rsaFormatter As New RSAPKCS1SignatureFormatter(rsa)
            rsaFormatter.SetHashAlgorithm(NameOf(SHA256))

            signedHash = rsaFormatter.CreateSignature(hash)
        End Using

        ' The sharedParameters, hash, and signedHash are used to later verify the signature.
    End Sub
End Module
using System.Security.Cryptography;
using System.Text;

using SHA256 alg = SHA256.Create();

byte[] data = Encoding.ASCII.GetBytes("Hello, from the .NET Docs!");
byte[] hash = alg.ComputeHash(data);

RSAParameters sharedParameters;
byte[] signedHash;

// Generate signature
using (RSA rsa = RSA.Create())
{
    sharedParameters = rsa.ExportParameters(false);

    RSAPKCS1SignatureFormatter rsaFormatter = new(rsa);
    rsaFormatter.SetHashAlgorithm(nameof(SHA256));

    signedHash = rsaFormatter.CreateSignature(hash);
}

// The sharedParameters, hash, and signedHash are used to later verify the signature.

Verificar uma assinatura

Para verificar se os dados foram assinados por uma parte específica, você precisa ter as seguintes informações:

  • A chave pública da parte que assinou os dados.
  • A assinatura digital.
  • Os dados que receberam um sinal.
  • O algoritmo de hash usado pelo signatário.

Para verificar uma assinatura assinada pela classe RSAPKCS1SignatureFormatter, use a classe RSAPKCS1SignatureDeformatter. A classe RSAPKCS1SignatureDeformatter precisa receber a chave pública do signatário. Para o RSA, você precisará, no mínimo, dos valores do RSAParameters.Modulus e RSAParameters.Exponent para especificar a chave pública. Uma forma de fazer isso é chamar RSA.ExportParameters durante a criação da assinatura e, em seguida, chamar RSA.ImportParameters durante o processo de verificação. A parte que gerou o par de chaves pública/privada deve fornecer esses valores. Primeiro, crie um objeto RSA para manter a chave pública que verificará a assinatura e, em seguida, inicialize uma estrutura RSAParameters para os valores de módulo e expoente que especificam a chave pública.

O código a seguir mostra o compartilhamento de uma estrutura RSAParameters. O RSA responsável por criar a assinatura exporta os parâmetros dela. Em seguida, os parâmetros são importados para a nova instância RSA responsável por verificar a assinatura.

A instância RSA é, por sua vez, transmitida para o construtor de um RSAPKCS1SignatureDeformatter para transferir a chave.

O exemplo a seguir ilustra esse processo. Neste exemplo, imagine que sharedParameters, hash e signedHash são fornecidos por uma parte remota. A parte remota assinou hash usando o algoritmo SHA256 para produzir a assinatura digital signedHash. O método RSAPKCS1SignatureDeformatter.VerifySignature verifica se a assinatura digital é válida e se ela foi usada para assinar o hash.

Imports System.Security.Cryptography
Imports System.Text

Module Program
    Sub Main()

        Dim alg As SHA256 = SHA256.Create()

        Dim data As Byte() = Encoding.UTF8.GetBytes("Hello, from the .NET Docs!")
        Dim hash As Byte() = alg.ComputeHash(data)

        Dim sharedParameters As RSAParameters
        Dim signedHash As Byte()

        ' Generate signature
        Using rsa As RSA = RSA.Create()
            sharedParameters = rsa.ExportParameters(True)
            Dim rsaFormatter As New RSAPKCS1SignatureFormatter(rsa)
            rsaFormatter.SetHashAlgorithm(NameOf(SHA256))

            signedHash = rsaFormatter.CreateSignature(hash)
        End Using

        ' Verify signature
        Using rsa As RSA = RSA.Create()
            rsa.ImportParameters(sharedParameters)

            Dim rsaDeformatter As New RSAPKCS1SignatureDeformatter(rsa)
            rsaDeformatter.SetHashAlgorithm(NameOf(SHA256))

            If rsaDeformatter.VerifySignature(hash, signedHash) Then
                Console.WriteLine("The signature is valid.")
            Else
                Console.WriteLine("The signature is not valid.")
            End If
        End Using
    End Sub
End Module
using System.Security.Cryptography;
using System.Text;

using SHA256 alg = SHA256.Create();

byte[] data = Encoding.ASCII.GetBytes("Hello, from the .NET Docs!");
byte[] hash = alg.ComputeHash(data);

RSAParameters sharedParameters;
byte[] signedHash;

// Generate signature
using (RSA rsa = RSA.Create())
{
    sharedParameters = rsa.ExportParameters(false);

    RSAPKCS1SignatureFormatter rsaFormatter = new(rsa);
    rsaFormatter.SetHashAlgorithm(nameof(SHA256));

    signedHash = rsaFormatter.CreateSignature(hash);
}

// Verify signature
using (RSA rsa = RSA.Create())
{
    rsa.ImportParameters(sharedParameters);

    RSAPKCS1SignatureDeformatter rsaDeformatter = new(rsa);
    rsaDeformatter.SetHashAlgorithm(nameof(SHA256));

    if (rsaDeformatter.VerifySignature(hash, signedHash))
    {
        Console.WriteLine("The signature is valid.");
    }
    else
    {
        Console.WriteLine("The signature is not valid.");
    }
}

Esse fragmento de código exibe "The signature is valid" se a assinatura for válida e "The signature is not valid", caso contrário.

Confira também