Idioma

Como usar a proteção de dados

Nota

Este artigo se aplica ao Windows.

Para obter informações sobre ASP.NET Core, consulte ASP.NET Core Data Protection.

.NET fornece acesso à DPAPI (API de proteção de dados), que permite criptografar dados usando informações da conta de usuário ou do computador atual. Ao usar o DPAPI, você evita o difícil problema de gerar e armazenar explicitamente uma chave criptográfica.

Use a ProtectedData classe para criptografar uma cópia de uma matriz de bytes. Você pode especificar que somente a mesma conta de usuário pode descriptografar os dados ou que qualquer conta no computador pode descriptografá-los. Para obter uma descrição detalhada das ProtectedData opções, consulte a DataProtectionScope enumeração.

Criptografar dados em um arquivo ou fluxo usando a proteção de dados

  1. Criar entropia aleatória.

  2. Chame o método estático Protect ao passar uma matriz de bytes para criptografar, a entropia e o escopo de proteção de dados.

  3. Escreva os dados criptografados em um arquivo ou fluxo.

Para descriptografar dados de um arquivo ou fluxo usando a proteção de dados

  1. Leia os dados criptografados de um arquivo ou fluxo.

  2. Chame o método estático Unprotect ao passar uma matriz de bytes a descriptografar e o escopo de proteção de dados.

Example

O exemplo de código a seguir mostra duas formas de criptografia e descriptografia. Primeiro, o código criptografa e descriptografa uma matriz de bytes na memória. Em seguida, o código criptografa uma cópia de uma matriz de bytes, salva-a em um arquivo, carrega os dados de volta do arquivo e descriptografa os dados. O exemplo exibe os dados originais, os dados criptografados e os dados descriptografados.

Important

ProtectedMemorysó está disponível para .NET Framework. ProtectedDataestá disponível no .NET e no .NET Framework.

Este exemplo compila e é executado quando o destino é o .NET no Windows. Para compilar o exemplo, adicione o System.Security.Cryptography.ProtectedData pacote NuGet.

using System.Security.Cryptography;
using System.Text;

try
{
    // Data Encryption - ProtectedData

    // Create the original data to be encrypted.
    byte[] toEncrypt = Encoding.ASCII.GetBytes("This is some data of any length.");

    // Create some random entropy.
    byte[] entropy = CreateRandomEntropy();

    Console.WriteLine();
    Console.WriteLine($"Original data: {Encoding.ASCII.GetString(toEncrypt)}");
    Console.WriteLine("Encrypting and writing to disk...");

    int bytesWritten;

    // Encrypt a copy of the data to the stream.
    using (FileStream writeStream = new("Data.dat", FileMode.OpenOrCreate))
    {
        bytesWritten = EncryptDataToStream(toEncrypt, entropy, DataProtectionScope.CurrentUser, writeStream);
    }

    Console.WriteLine("Reading data from disk and decrypting...");

    // Read from the stream and decrypt the data.
    byte[] decryptData;
    using (FileStream readStream = new("Data.dat", FileMode.Open))
    {
        decryptData = DecryptDataFromStream(entropy, DataProtectionScope.CurrentUser, readStream, bytesWritten);
    }

    Console.WriteLine($"Decrypted data: {Encoding.ASCII.GetString(decryptData)}");
}
catch (Exception e)
{
    Console.WriteLine($"ERROR: {e.Message}");
}

static byte[] CreateRandomEntropy()
{
    // Create a byte array to hold the random value and fill it with a random value.
    byte[] entropy = new byte[16];
    RandomNumberGenerator.Fill(entropy);

    return entropy;
}

static int EncryptDataToStream(byte[] buffer, byte[] entropy, DataProtectionScope scope, Stream stream)
{
    ArgumentNullException.ThrowIfNull(buffer);
    ArgumentOutOfRangeException.ThrowIfZero(buffer.Length, nameof(buffer));
    ArgumentNullException.ThrowIfNull(entropy);
    ArgumentOutOfRangeException.ThrowIfZero(entropy.Length, nameof(entropy));
    ArgumentNullException.ThrowIfNull(stream);

    int length = 0;

    // Encrypt the data and store the result in a new byte array. The original data remains unchanged.
    byte[] encryptedData = ProtectedData.Protect(buffer, entropy, scope);

    // Write the encrypted data to a stream.
    if (stream.CanWrite)
    {
        stream.Write(encryptedData, 0, encryptedData.Length);
        length = encryptedData.Length;
    }

    // Return the length that was written to the stream.
    return length;
}

static byte[] DecryptDataFromStream(byte[] entropy, DataProtectionScope scope, Stream stream, int length)
{
    ArgumentNullException.ThrowIfNull(stream);
    ArgumentOutOfRangeException.ThrowIfZero(length, nameof(length));
    ArgumentNullException.ThrowIfNull(entropy);
    ArgumentOutOfRangeException.ThrowIfZero(entropy.Length, nameof(entropy));

    if (!stream.CanRead)
        throw new IOException("Could not read the stream.");

    byte[] inBuffer = new byte[length];
    stream.ReadExactly(inBuffer, 0, length);

    // Return the decrypted data.
    return ProtectedData.Unprotect(inBuffer, entropy, scope);
}
Imports System.IO
Imports System.Security.Cryptography
Imports System.Text

Public Module DataProtectionSample

    Sub Main()
        Try
            ' Data Encryption - ProtectedData

            ' Create the original data to be encrypted.
            Dim toEncrypt As Byte() = Encoding.ASCII.GetBytes("This is some data of any length.")

            ' Create some random entropy.
            Dim entropy As Byte() = CreateRandomEntropy()

            Console.WriteLine()
            Console.WriteLine($"Original data: {Encoding.ASCII.GetString(toEncrypt)}")
            Console.WriteLine("Encrypting and writing to disk...")

            Dim bytesWritten As Integer

            ' Encrypt a copy of the data to the stream.
            Using writeStream As New FileStream("Data.dat", FileMode.OpenOrCreate)
                bytesWritten = EncryptDataToStream(toEncrypt, entropy, DataProtectionScope.CurrentUser, writeStream)
            End Using

            Console.WriteLine("Reading data from disk and decrypting...")

            ' Read from the stream and decrypt the data.
            Dim decryptData As Byte()
            Using readStream As New FileStream("Data.dat", FileMode.Open)
                decryptData = DecryptDataFromStream(entropy, DataProtectionScope.CurrentUser, readStream, bytesWritten)
            End Using

            Console.WriteLine($"Decrypted data: {Encoding.ASCII.GetString(decryptData)}")

        Catch e As Exception
            Console.WriteLine($"ERROR: {e.Message}")
        End Try
    End Sub

    Function CreateRandomEntropy() As Byte()
        ' Create a byte array to hold the random value and fill it with a random value.
        Dim entropy(15) As Byte
        RandomNumberGenerator.Fill(entropy)

        Return entropy
    End Function

    Function EncryptDataToStream(buffer As Byte(), entropy As Byte(), scope As DataProtectionScope, stream As Stream) As Integer
        ArgumentNullException.ThrowIfNull(buffer)
        ArgumentOutOfRangeException.ThrowIfZero(buffer.Length, NameOf(buffer))
        ArgumentNullException.ThrowIfNull(entropy)
        ArgumentOutOfRangeException.ThrowIfZero(entropy.Length, NameOf(entropy))
        ArgumentNullException.ThrowIfNull(stream)

        Dim length As Integer = 0

        ' Encrypt the data and store the result in a new byte array. The original data remains unchanged.
        Dim encryptedData As Byte() = ProtectedData.Protect(buffer, entropy, scope)

        ' Write the encrypted data to a stream.
        If stream.CanWrite Then
            stream.Write(encryptedData, 0, encryptedData.Length)
            length = encryptedData.Length
        End If

        ' Return the length that was written to the stream.
        Return length
    End Function

    Function DecryptDataFromStream(entropy As Byte(), scope As DataProtectionScope, stream As Stream, length As Integer) As Byte()
        ArgumentNullException.ThrowIfNull(stream)
        ArgumentOutOfRangeException.ThrowIfZero(length, NameOf(length))
        ArgumentNullException.ThrowIfNull(entropy)
        ArgumentOutOfRangeException.ThrowIfZero(entropy.Length, NameOf(entropy))

        If Not stream.CanRead Then
            Throw New IOException("Could not read the stream.")
        End If

        Dim inBuffer(length - 1) As Byte
        stream.ReadExactly(inBuffer, 0, length)

        ' Return the decrypted data.
        Return ProtectedData.Unprotect(inBuffer, entropy, scope)
    End Function

End Module

Consulte também