Note

Access to this page requires authorization. You can try signing in or .

Access to this page requires authorization. You can try .

How to: Use Data Protection

Note

This article applies to Windows.

For information about ASP.NET Core, see ASP.NET Core Data Protection.

.NET provides access to the data protection API (DPAPI), which allows you to encrypt data using information from the current user account or computer. When you use the DPAPI, you alleviate the difficult problem of explicitly generating and storing a cryptographic key.

Use the ProtectedData class to encrypt a copy of an array of bytes. You can specify that data encrypted by the current user account can be decrypted only by the same user account, or you can specify that data encrypted by the current user account can be decrypted by any account on the computer. See the DataProtectionScope enumeration for a detailed description of ProtectedData options.

Encrypt data to a file or stream using data protection

  1. Create random entropy.

  2. Call the static Protect method while passing an array of bytes to encrypt, the entropy, and the data protection scope.

  3. Write the encrypted data to a file or stream.

To decrypt data from a file or stream using data protection

  1. Read the encrypted data from a file or stream.

  2. Call the static Unprotect method while passing an array of bytes to decrypt and the data protection scope.

Example

The following code example demonstrates two forms of encryption and decryption. First, the code example encrypts and then decrypts an in-memory array of bytes. Next, the code example encrypts a copy of a byte array, saves it to a file, loads the data back from the file, and then decrypts the data. The example displays the original data, the encrypted data, and the decrypted data.

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

public class MemoryProtectionSample
{
 public static void Main() => Run();

 public static void Run()
 {
 try
 {
 ///////////////////////////////
 //
 // Memory Encryption - ProtectedMemory
 //
 ///////////////////////////////

 // Create the original data to be encrypted (The data length should be a multiple of 16).
 byte[] toEncrypt = UnicodeEncoding.ASCII.GetBytes("ThisIsSomeData16");

 Console.WriteLine($"Original data: {UnicodeEncoding.ASCII.GetString(toEncrypt)}");
 Console.WriteLine("Encrypting...");

 // Encrypt the data in memory.
 EncryptInMemoryData(toEncrypt, MemoryProtectionScope.SameLogon);

 Console.WriteLine($"Encrypted data: {UnicodeEncoding.ASCII.GetString(toEncrypt)}");
 Console.WriteLine("Decrypting...");

 // Decrypt the data in memory.
 DecryptInMemoryData(toEncrypt, MemoryProtectionScope.SameLogon);

 Console.WriteLine($"Decrypted data: {UnicodeEncoding.ASCII.GetString(toEncrypt)}");

 ///////////////////////////////
 //
 // Data Encryption - ProtectedData
 //
 ///////////////////////////////

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

 // Create a file.
 FileStream fStream = new FileStream("Data.dat", FileMode.OpenOrCreate);

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

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

 // Encrypt a copy of the data to the stream.
 int bytesWritten = EncryptDataToStream(toEncrypt, entropy, DataProtectionScope.CurrentUser, fStream);

 fStream.Close();

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

 // Open the file.
 fStream = new FileStream("Data.dat", FileMode.Open);

 // Read from the stream and decrypt the data.
 byte[] decryptData = DecryptDataFromStream(entropy, DataProtectionScope.CurrentUser, fStream, bytesWritten);

 fStream.Close();

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

 public static void EncryptInMemoryData(byte[] Buffer, MemoryProtectionScope Scope )
 {
 if (Buffer == null)
 throw new ArgumentNullException(nameof(Buffer));
 if (Buffer.Length <= 0)
 throw new ArgumentException("The buffer length was 0.", nameof(Buffer));

 // Encrypt the data in memory. The result is stored in the same array as the original data.
 ProtectedMemory.Protect(Buffer, Scope);
 }

 public static void DecryptInMemoryData(byte[] Buffer, MemoryProtectionScope Scope)
 {
 if (Buffer == null)
 throw new ArgumentNullException(nameof(Buffer));
 if (Buffer.Length <= 0)
 throw new ArgumentException("The buffer length was 0.", nameof(Buffer));

 // Decrypt the data in memory. The result is stored in the same array as the original data.
 ProtectedMemory.Unprotect(Buffer, Scope);
 }

 public static byte[] CreateRandomEntropy()
 {
 // Create a byte array to hold the random value.
 byte[] entropy = new byte[16];

 // Create a new instance of the RNGCryptoServiceProvider.
 // Fill the array with a random value.
 new RNGCryptoServiceProvider().GetBytes(entropy);

 // Return the array.
 return entropy;
 }

 public static int EncryptDataToStream(byte[] Buffer, byte[] Entropy, DataProtectionScope Scope, Stream S)
 {
 if (Buffer == null)
 throw new ArgumentNullException(nameof(Buffer));
 if (Buffer.Length <= 0)
 throw new ArgumentException("The buffer length was 0.", nameof(Buffer));
 if (Entropy == null)
 throw new ArgumentNullException(nameof(Entropy));
 if (Entropy.Length <= 0)
 throw new ArgumentException("The entropy length was 0.", nameof(Entropy));
 if (S == null)
 throw new ArgumentNullException(nameof(S));

 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 (S.CanWrite && encryptedData != null)
 {
 S.Write(encryptedData, 0, encryptedData.Length);

 length = encryptedData.Length;
 }

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

 public static byte[] DecryptDataFromStream(byte[] Entropy, DataProtectionScope Scope, Stream S, int Length)
 {
 if (S == null)
 throw new ArgumentNullException(nameof(S));
 if (Length <= 0 )
 throw new ArgumentException("The given length was 0.", nameof(Length));
 if (Entropy == null)
 throw new ArgumentNullException(nameof(Entropy));
 if (Entropy.Length <= 0)
 throw new ArgumentException("The entropy length was 0.", nameof(Entropy));

 byte[] inBuffer = new byte[Length];
 byte[] outBuffer;

 // Read the encrypted data from a stream.
 if (S.CanRead)
 {
 S.Read(inBuffer, 0, Length);

 outBuffer = ProtectedData.Unprotect(inBuffer, Entropy, Scope);
 }
 else
 {
 throw new IOException("Could not read the stream.");
 }

 // Return the decrypted data
 return outBuffer;
 }
}
Imports System.IO
Imports System.Text
Imports System.Security.Cryptography



Public Module MemoryProtectionSample

 Sub Main()
 Run()

 End Sub


 Sub Run()
 Try

 ''''''''''''''''''''''''''''''''''''
 '
 ' Memory Encryption - ProtectedMemory
 '
 ''''''''''''''''''''''''''''''''''''
 ' Create the original data to be encrypted (The data length should be a multiple of 16).
 Dim toEncrypt As Byte() = UnicodeEncoding.ASCII.GetBytes("ThisIsSomeData16")

 Console.WriteLine("Original data: " + UnicodeEncoding.ASCII.GetString(toEncrypt))
 Console.WriteLine("Encrypting...")

 ' Encrypt the data in memory.
 EncryptInMemoryData(toEncrypt, MemoryProtectionScope.SameLogon)

 Console.WriteLine("Encrypted data: " + UnicodeEncoding.ASCII.GetString(toEncrypt))
 Console.WriteLine("Decrypting...")

 ' Decrypt the data in memory.
 DecryptInMemoryData(toEncrypt, MemoryProtectionScope.SameLogon)

 Console.WriteLine("Decrypted data: " + UnicodeEncoding.ASCII.GetString(toEncrypt))


 ''''''''''''''''''''''''''''''''''''
 '
 ' Data Encryption - ProtectedData
 '
 ''''''''''''''''''''''''''''''''''''
 ' Create the original data to be encrypted
 toEncrypt = UnicodeEncoding.ASCII.GetBytes("This is some data of any length.")

 ' Create a file.
 Dim fStream As New FileStream("Data.dat", FileMode.OpenOrCreate)

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

 Console.WriteLine()
 Console.WriteLine("Original data: " + UnicodeEncoding.ASCII.GetString(toEncrypt))
 Console.WriteLine("Encrypting and writing to disk...")

 ' Encrypt a copy of the data to the stream.
 Dim bytesWritten As Integer = EncryptDataToStream(toEncrypt, entropy, DataProtectionScope.CurrentUser, fStream)

 fStream.Close()

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

 ' Open the file.
 fStream = New FileStream("Data.dat", FileMode.Open)

 ' Read from the stream and decrypt the data.
 Dim decryptData As Byte() = DecryptDataFromStream(entropy, DataProtectionScope.CurrentUser, fStream, bytesWritten)

 fStream.Close()

 Console.WriteLine("Decrypted data: " + UnicodeEncoding.ASCII.GetString(decryptData))


 Catch e As Exception
 Console.WriteLine("ERROR: " + e.Message)
 End Try

 End Sub



 Sub EncryptInMemoryData(ByVal Buffer() As Byte, ByVal Scope As MemoryProtectionScope)
 If Buffer Is Nothing Then
 Throw New ArgumentNullException("Buffer")
 End If
 If Buffer.Length <= 0 Then
 Throw New ArgumentException("Buffer")
 End If

 ' Encrypt the data in memory. The result is stored in the same array as the original data.
 ProtectedMemory.Protect(Buffer, Scope)

 End Sub


 Sub DecryptInMemoryData(ByVal Buffer() As Byte, ByVal Scope As MemoryProtectionScope)
 If Buffer Is Nothing Then
 Throw New ArgumentNullException("Buffer")
 End If
 If Buffer.Length <= 0 Then
 Throw New ArgumentException("Buffer")
 End If

 ' Decrypt the data in memory. The result is stored in the same array as the original data.
 ProtectedMemory.Unprotect(Buffer, Scope)

 End Sub


 Function CreateRandomEntropy() As Byte()
 ' Create a byte array to hold the random value.
 Dim entropy(15) As Byte

 ' Create a new instance of the RNGCryptoServiceProvider.
 ' Fill the array with a random value.
 Dim RNG As New RNGCryptoServiceProvider()

 RNG.GetBytes(entropy)

 ' Return the array.
 Return entropy

 End Function 'CreateRandomEntropy



 Function EncryptDataToStream(ByVal Buffer() As Byte, ByVal Entropy() As Byte, ByVal Scope As DataProtectionScope, ByVal S As Stream) As Integer
 If Buffer Is Nothing Then
 Throw New ArgumentNullException("Buffer")
 End If
 If Buffer.Length <= 0 Then
 Throw New ArgumentException("Buffer")
 End If
 If Entropy Is Nothing Then
 Throw New ArgumentNullException("Entropy")
 End If
 If Entropy.Length <= 0 Then
 Throw New ArgumentException("Entropy")
 End If
 If S Is Nothing Then
 Throw New ArgumentNullException("S")
 End If
 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 S.CanWrite AndAlso Not (encryptedData Is Nothing) Then
 S.Write(encryptedData, 0, encryptedData.Length)

 length = encryptedData.Length
 End If

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

 End Function 'EncryptDataToStream


 Function DecryptDataFromStream(ByVal Entropy() As Byte, ByVal Scope As DataProtectionScope, ByVal S As Stream, ByVal Length As Integer) As Byte()
 If S Is Nothing Then
 Throw New ArgumentNullException("S")
 End If
 If Length <= 0 Then
 Throw New ArgumentException("Length")
 End If
 If Entropy Is Nothing Then
 Throw New ArgumentNullException("Entropy")
 End If
 If Entropy.Length <= 0 Then
 Throw New ArgumentException("Entropy")
 End If


 Dim inBuffer(Length - 1) As Byte
 Dim outBuffer() As Byte

 ' Read the encrypted data from a stream.
 If S.CanRead Then
 S.Read(inBuffer, 0, Length)

 outBuffer = ProtectedData.Unprotect(inBuffer, Entropy, Scope)
 Else
 Throw New IOException("Could not read the stream.")
 End If

 ' Return the unencrypted data as byte array. 
 Return outBuffer

 End Function 'DecryptDataFromStream 
End Module 'MemoryProtectionSample

Compiling the Code

This example compiles and runs only when targeting .NET Framework and running on Windows.

See also


Feedback

Was this page helpful?

Additional resources