Partilhar via


Modelo de criptografia .NET

O .NET fornece implementações de muitos algoritmos criptográficos padrão.

Herança de objeto

O sistema de criptografia .NET implementa um padrão extensível de herança de classe derivada. A hierarquia é a seguinte:

Esse padrão de classes derivadas permite adicionar um novo algoritmo ou uma nova implementação de um algoritmo existente. Por exemplo, para criar um novo algoritmo de chave pública, você herdaria da AsymmetricAlgorithm classe. Para criar uma nova implementação de um algoritmo específico, você criaria uma classe derivada não abstrata desse algoritmo.

No futuro, este modelo de herança não é usado para novos tipos de primitivos como AesGcm ou Shake128. Estes algoritmos são sealed. Se você precisar de um padrão de extensibilidade ou abstração sobre esses tipos, a implementação da abstração é de responsabilidade do desenvolvedor.

One-shot APIs

A partir do .NET 5, APIs mais simples foram introduzidas para hashing e HMAC. Embora um pouco menos flexíveis, estas APIs one-shot :

  • São mais fáceis de usar (e menos propensos a uso indevido)
  • Reduzir alocações ou são livres de alocação
  • São thread safe
  • Use a melhor implementação disponível para a plataforma

As primitivas hashing e HMAC expõem uma API one-shot por meio de um método estático HashData no tipo, como SHA256.HashData. As APIs estáticas não oferecem nenhum mecanismo de extensibilidade integrado. Se você estiver implementando seus próprios algoritmos, é recomendável também oferecer APIs estáticas semelhantes do algoritmo.

A RandomNumberGenerator classe também oferece métodos estáticos para criar ou preencher buffers com dados aleatórios criptográficos. Esses métodos sempre usam o gerador de números pseudoaleatórios criptograficamente seguro (CSPRNG) do sistema.

Como os algoritmos são implementados no .NET

Como exemplo das diferentes implementações disponíveis para um algoritmo, considere algoritmos simétricos. A base para todos os algoritmos simétricos é SymmetricAlgorithm, que é herdado por Aes, TripleDESe outros que não são mais recomendados.

Aes é herdada por AesCryptoServiceProvider, AesCnge AesManaged.

No .NET Framework no Windows:

  • *CryptoServiceProvider classes de algoritmo, como AesCryptoServiceProvider, são wrappers em torno da implementação da API de Criptografia do Windows (CAPI) de um algoritmo.
  • *Cng classes de algoritmo, como ECDiffieHellmanCng, são wrappers em torno da implementação do Windows Cryptography Next Generation (CNG).
  • *Managed classes, como AesManaged, são escritas inteiramente em código gerenciado. *Managed as implementações não são certificadas pelo Federal Information Processing Standards (FIPS) e podem ser mais lentas do que as *CryptoServiceProvider classes e *Cng wrapper.

No .NET Core e no .NET 5 e versões posteriores, todas as classes de implementação (*CryptoServiceProvider, *Managede *Cng) são wrappers para os algoritmos do sistema operacional (SO). Se os algoritmos do sistema operacional tiverem certificação FIPS, o .NET usará algoritmos certificados por FIPS. Para obter mais informações, consulte Criptografia entre plataformas.

Na maioria dos casos, você não precisa fazer referência direta a uma classe de implementação de algoritmo, como AesCryptoServiceProvider. Os métodos e propriedades de que você normalmente precisa estão na classe de algoritmo base, como Aes. Crie uma instância de uma classe de implementação padrão usando um método de fábrica na classe de algoritmo base e consulte a classe de algoritmo base. Por exemplo, consulte a linha de código realçada no exemplo a seguir:

using System.Security.Cryptography;

try
{
    using (FileStream fileStream = new("TestData.txt", FileMode.OpenOrCreate))
    {
        using (Aes aes = Aes.Create())
        {
            byte[] key =
            {
                0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
                0x09, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16
            };
            aes.Key = key;

            byte[] iv = aes.IV;
            fileStream.Write(iv, 0, iv.Length);

            using (CryptoStream cryptoStream = new(
                fileStream,
                aes.CreateEncryptor(),
                CryptoStreamMode.Write))
            {
                // By default, the StreamWriter uses UTF-8 encoding.
                // To change the text encoding, pass the desired encoding as the second parameter.
                // For example, new StreamWriter(cryptoStream, Encoding.Unicode).
                using (StreamWriter encryptWriter = new(cryptoStream))
                {
                    encryptWriter.WriteLine("Hello World!");
                }
            }
        }
    }

    Console.WriteLine("The file was encrypted.");
}
catch (Exception ex)
{
    Console.WriteLine($"The encryption failed. {ex}");
}
Imports System
Imports System.IO
Imports System.Security.Cryptography

Module Module1
    Sub Main()
        Try
            ' Create a file stream
            Using fileStream As New FileStream("TestData.txt", FileMode.OpenOrCreate)

                ' Create a new instance of the default Aes implementation class  
                ' and configure encryption key.
                Using aes As Aes = Aes.Create()
                    'Encryption key used to encrypt the stream.
                    'The same value must be used to encrypt and decrypt the stream.
                    Dim key As Byte() = {
                        &H1, &H2, &H3, &H4, &H5, &H6, &H7, &H8,
                        &H9, &H10, &H11, &H12, &H13, &H14, &H15, &H16
                    }

                    aes.Key = key

                    ' Stores IV at the beginning of the file.
                    ' This information will be used for decryption.
                    Dim iv As Byte() = aes.IV
                    fileStream.Write(iv, 0, iv.Length)

                    ' Create a CryptoStream, pass it the FileStream, and encrypt
                    ' it with the Aes class.
                    Using cryptoStream As New CryptoStream(fileStream, aes.CreateEncryptor(), CryptoStreamMode.Write)

                        ' By default, the StreamWriter uses UTF-8 encoding.
                        ' To change the text encoding, pass the desired encoding as the second parameter.
                        ' For example, New StreamWriter(cryptoStream, Encoding.Unicode).
                        Using sWriter As New StreamWriter(cryptoStream)

                            'Write to the stream.
                            sWriter.WriteLine("Hello World!")
                        End Using
                    End Using
                End Using
            End Using

            'Inform the user that the message was written  
            'to the stream.  
            Console.WriteLine("The text was encrypted.")
        Catch
            'Inform the user that an exception was raised.  
            Console.WriteLine("The encryption failed.")
            Throw
        End Try
    End Sub
End Module

Escolha um algoritmo

Você pode selecionar um algoritmo por diferentes motivos: por exemplo, para integridade de dados, para privacidade de dados ou para gerar uma chave. Os algoritmos simétricos e de hash destinam-se a proteger os dados por razões de integridade (proteger contra alterações) ou de privacidade (proteger contra visualização). Os algoritmos de hash são usados principalmente para integridade de dados.

Aqui está uma lista de algoritmos recomendados por aplicação:

Consulte também