Język

Jak używać ochrony danych

Note

Ten artykuł dotyczy systemu Windows.

Aby uzyskać informacje o ASP.NET Core, zobacz ASP.NET Core Data Protection.

.NET zapewnia dostęp do interfejsu API ochrony danych (DPAPI), który umożliwia szyfrowanie danych przy użyciu informacji z bieżącego konta użytkownika lub komputera. W przypadku korzystania z interfejsu DPAPI należy unikać trudnego problemu z jawnym generowaniem i przechowywaniem klucza kryptograficznego.

ProtectedData Użyj klasy , aby zaszyfrować kopię tablicy bajtów. Można określić, że tylko to samo konto użytkownika może odszyfrować dane lub że dowolne konto na komputerze może je odszyfrować. Szczegółowy opis opcji ProtectedData można znaleźć w wyliczeniu DataProtectionScope.

Szyfrowanie danych do pliku lub strumienia przy użyciu ochrony danych

  1. Utwórz losową entropię.

  2. Wywołaj statyczną metodę Protect, przekazując tablicę bajtów do zaszyfrowania, wartość entropii oraz zakres ochrony danych.

  3. Zapisz zaszyfrowane dane w pliku lub strumieniu.

Aby odszyfrować dane z pliku lub strumienia przy użyciu ochrony danych

  1. Odczytywanie zaszyfrowanych danych z pliku lub strumienia.

  2. Wywołaj metodę statyczną Unprotect, przekazując tablicę bajtów do odszyfrowania oraz zakres ochrony danych.

Example

Poniższy przykład kodu przedstawia dwie formy szyfrowania i odszyfrowywania. Najpierw kod szyfruje, a następnie odszyfrowuje tablicę bajtów w pamięci. Następnie kod szyfruje kopię tablicy bajtów, zapisuje ją w pliku, ładuje dane z powrotem z pliku, a następnie odszyfrowuje dane. W przykładzie są wyświetlane oryginalne dane, zaszyfrowane dane i odszyfrowane dane.

Important

ProtectedMemoryjest dostępna tylko dla platformy .NET Framework. ProtectedData jest dostępny na platformach .NET i .NET Framework.

Ten przykład kompiluje się i działa, gdy jako platformę docelową wybierzesz platformę .NET w systemie Windows. Aby skompilować przykład, dodaj pakiet NuGet System.Security.Cryptography.ProtectedData.

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

Zobacz także