言語

データ保護の使用方法

Note

この記事は Windows に適用されます。

ASP.NET Coreの詳細については、「データ保護の ASP.NET Core」を参照してください。

.NETは、現在のユーザー アカウントまたはコンピューターからの情報を使用してデータを暗号化できるデータ保護 API (DPAPI) へのアクセスを提供します。 DPAPI を使用すると、暗号化キーを明示的に生成して格納するという困難な問題を回避できます。

ProtectedData クラスを使用して、バイト配列のコピーを暗号化します。 データの暗号化を解除できるのは同じユーザー アカウントのみ、またはコンピューター上の任意のアカウントで暗号化を解除できるように指定できます。 ProtectedDataオプションの詳細については、DataProtectionScope列挙体を参照してください。

データ保護を使用してファイルまたはストリームにデータを暗号化する

  1. ランダム エントロピを作成します。

  2. 暗号化するバイト配列、エントロピ、およびデータ保護スコープを渡しながら、静的 Protect メソッドを呼び出します。

  3. 暗号化されたデータをファイルまたはストリームに書き込みます。

データ保護を使用してファイルまたはストリームからデータを復号化するには

  1. 暗号化されたデータをファイルまたはストリームから読み取ります。

  2. 復号化するバイト配列とデータ保護スコープを渡しながら、静的な Unprotect メソッドを呼び出します。

Example

次のコード例は、2 つの形式の暗号化と暗号化解除を示しています。 最初に、コードはバイトのメモリ内配列を暗号化して復号化します。 次に、コードはバイト配列のコピーを暗号化し、ファイルに保存し、ファイルからデータを読み込んでから、データの暗号化を解除します。 この例では、元のデータ、暗号化されたデータ、および復号化されたデータを表示します。

Important

ProtectedMemoryは、.NET Framework でのみ使用できます。 ProtectedDataは、.NET および .NET Framework で使用できます。

このサンプルは、Windowsで.NETをターゲットにしたときにコンパイルされ、実行されます。 サンプルをコンパイルするには、 System.Security.Cryptography.ProtectedData 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

こちらも参照ください