From 379d951da5f85d942ca46241995a6e178fbf204c Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 21 Jul 2026 23:25:37 +0000 Subject: [PATCH 1/8] Initial plan From 0ec9a1a91686015834ee49c857bd4fe8a8f7d06c Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 21 Jul 2026 23:28:14 +0000 Subject: [PATCH 2/8] Clarify data protection package requirements --- docs/standard/security/how-to-use-data-protection.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/docs/standard/security/how-to-use-data-protection.md b/docs/standard/security/how-to-use-data-protection.md index 82d6a27053a4f..0d38af10fa58a 100644 --- a/docs/standard/security/how-to-use-data-protection.md +++ b/docs/standard/security/how-to-use-data-protection.md @@ -22,6 +22,8 @@ ms.assetid: 606698b0-cb1a-42ca-beeb-0bea34205d20 > [!NOTE] > This article applies to Windows. > +> If you target .NET on Windows, install the [`System.Security.Cryptography.ProtectedData`](https://www.nuget.org/packages/System.Security.Cryptography.ProtectedData/) NuGet package before you use or . +> > For information about ASP.NET Core, see [ASP.NET Core Data Protection](/aspnet/core/security/data-protection/introduction). .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. @@ -57,6 +59,8 @@ This example compiles and runs only when targeting .NET Framework and running on - Include the , , , and namespace. +- If you target .NET instead of .NET Framework, install the [`System.Security.Cryptography.ProtectedData`](https://www.nuget.org/packages/System.Security.Cryptography.ProtectedData/) NuGet package to use and . .NET doesn't support or `MemoryProtectionScope`, so the full sample in this article doesn't compile on .NET. + ## See also - [Cryptography Model](cryptography-model.md) From 57c0e051f3d9f839fe57ecdeb10ecf53b7d12913 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 22 Jul 2026 00:16:48 +0000 Subject: [PATCH 3/8] Add example note for ProtectedMemory limitation --- docs/standard/security/how-to-use-data-protection.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/docs/standard/security/how-to-use-data-protection.md b/docs/standard/security/how-to-use-data-protection.md index 0d38af10fa58a..942361ba19582 100644 --- a/docs/standard/security/how-to-use-data-protection.md +++ b/docs/standard/security/how-to-use-data-protection.md @@ -48,6 +48,9 @@ Use the class to encrypt a cop 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. +> [!NOTE] +> If you target .NET instead of .NET Framework, isn't available. The `EncryptInMemoryData` and `DecryptInMemoryData` methods rely on that API, so those methods don't compile on .NET. + [!code-csharp[DPAPI-HowTO#1](../../../samples/snippets/csharp/VS_Snippets_CLR/DPAPI-HowTO/cs/sample.cs#1)] [!code-vb[DPAPI-HowTO#1](../../../samples/snippets/visualbasic/VS_Snippets_CLR/DPAPI-HowTO/vb/sample.vb#1)] From 7d5f75328861d65703d33ffdfb3410029fe5b348 Mon Sep 17 00:00:00 2001 From: "Andy De George (from Dev Box)" Date: Wed, 22 Jul 2026 13:35:54 -0700 Subject: [PATCH 4/8] Remove github copilots work and redesign with copilot locally --- .../security/how-to-use-data-protection.md | 30 ++++--- .../csharp/DataProtectionSample.csproj | 42 +++++++++ .../framework/csharp}/sample.cs | 22 ++--- .../framework/csharp/snippets.5000.json | 3 + .../framework/vb/DataProtectionSample.vbproj | 56 ++++++++++++ .../framework}/vb/sample.vb | 45 +++------- .../framework/vb/snippets.5000.json | 3 + .../net/csharp/DataProtectionSample.csproj | 14 +++ .../net/csharp/sample.cs | 90 +++++++++++++++++++ .../net/vb/DataProtectionSample.vbproj | 13 +++ .../net/vb/sample.vb | 90 +++++++++++++++++++ .../DPAPI-HowTO/cs/sample.csproj | 12 --- 12 files changed, 350 insertions(+), 70 deletions(-) create mode 100644 docs/standard/security/snippets/how-to-use-data-protection/framework/csharp/DataProtectionSample.csproj rename {samples/snippets/csharp/VS_Snippets_CLR/DPAPI-HowTO/cs => docs/standard/security/snippets/how-to-use-data-protection/framework/csharp}/sample.cs (88%) create mode 100644 docs/standard/security/snippets/how-to-use-data-protection/framework/csharp/snippets.5000.json create mode 100644 docs/standard/security/snippets/how-to-use-data-protection/framework/vb/DataProtectionSample.vbproj rename {samples/snippets/visualbasic/VS_Snippets_CLR/DPAPI-HowTO => docs/standard/security/snippets/how-to-use-data-protection/framework}/vb/sample.vb (80%) create mode 100644 docs/standard/security/snippets/how-to-use-data-protection/framework/vb/snippets.5000.json create mode 100644 docs/standard/security/snippets/how-to-use-data-protection/net/csharp/DataProtectionSample.csproj create mode 100644 docs/standard/security/snippets/how-to-use-data-protection/net/csharp/sample.cs create mode 100644 docs/standard/security/snippets/how-to-use-data-protection/net/vb/DataProtectionSample.vbproj create mode 100644 docs/standard/security/snippets/how-to-use-data-protection/net/vb/sample.vb delete mode 100644 samples/snippets/csharp/VS_Snippets_CLR/DPAPI-HowTO/cs/sample.csproj diff --git a/docs/standard/security/how-to-use-data-protection.md b/docs/standard/security/how-to-use-data-protection.md index 942361ba19582..4ddd5373decad 100644 --- a/docs/standard/security/how-to-use-data-protection.md +++ b/docs/standard/security/how-to-use-data-protection.md @@ -1,7 +1,8 @@ --- title: "How to: Use Data Protection" description: Learn how to use data protection by accessing the data protection API (DPAPI) in .NET. -ms.date: 07/14/2020 +ms.date: 07/22/2026 +ai-usage: ai-assisted dev_langs: - "csharp" - "vb" @@ -22,8 +23,6 @@ ms.assetid: 606698b0-cb1a-42ca-beeb-0bea34205d20 > [!NOTE] > This article applies to Windows. > -> If you target .NET on Windows, install the [`System.Security.Cryptography.ProtectedData`](https://www.nuget.org/packages/System.Security.Cryptography.ProtectedData/) NuGet package before you use or . -> > For information about ASP.NET Core, see [ASP.NET Core Data Protection](/aspnet/core/security/data-protection/introduction). .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. @@ -34,7 +33,7 @@ Use the class to encrypt a cop 1. Create random entropy. -2. Call the static method while passing an array of bytes to encrypt, the entropy, and the data protection scope. +2. Call the static method while passing an array of bytes to encrypt, the entropy, and (if applicable) the data protection scope. 3. Write the encrypted data to a file or stream. @@ -42,7 +41,7 @@ Use the class to encrypt a cop 1. Read the encrypted data from a file or stream. -2. Call the static method while passing an array of bytes to decrypt and the data protection scope. +2. Call the static method while passing an array of bytes to decrypt and (if applicable) the data protection scope. ## Example @@ -51,18 +50,25 @@ The following code example demonstrates two forms of encryption and decryption. > [!NOTE] > If you target .NET instead of .NET Framework, isn't available. The `EncryptInMemoryData` and `DecryptInMemoryData` methods rely on that API, so those methods don't compile on .NET. -[!code-csharp[DPAPI-HowTO#1](../../../samples/snippets/csharp/VS_Snippets_CLR/DPAPI-HowTO/cs/sample.cs#1)] -[!code-vb[DPAPI-HowTO#1](../../../samples/snippets/visualbasic/VS_Snippets_CLR/DPAPI-HowTO/vb/sample.vb#1)] - -## Compiling the Code +### [.NET Framework](#tab/net-framework) -This example compiles and runs only when targeting .NET Framework and running on Windows. +To compile the sample: - Include a reference to `System.Security.dll`. -- Include the , , , and namespace. +This sample compiles and runs when targeting .NET Framework on Windows. To compile the sample, add a library reference to `System.Security.dll`. + +:::code language="csharp" source="./snippets/how-to-use-data-protection/framework/csharp/sample.cs" id="FullSample"::: +:::code language="vb" source="./snippets/how-to-use-data-protection/framework/vb/sample.vb"::: + +### [.NET](#tab/net) -- If you target .NET instead of .NET Framework, install the [`System.Security.Cryptography.ProtectedData`](https://www.nuget.org/packages/System.Security.Cryptography.ProtectedData/) NuGet package to use and . .NET doesn't support or `MemoryProtectionScope`, so the full sample in this article doesn't compile on .NET. +This sample compiles and runs when targeting .NET on Windows. To compile the sample, add [`System.Security.Cryptography.ProtectedData`](https://www.nuget.org/packages/System.Security.Cryptography.ProtectedData/) NuGet package. + +:::code language="csharp" source="./snippets/how-to-use-data-protection/net/csharp/sample.cs"::: +:::code language="vb" source="./snippets/how-to-use-data-protection/net/vb/sample.vb"::: + +--- ## See also diff --git a/docs/standard/security/snippets/how-to-use-data-protection/framework/csharp/DataProtectionSample.csproj b/docs/standard/security/snippets/how-to-use-data-protection/framework/csharp/DataProtectionSample.csproj new file mode 100644 index 0000000000000..1bebf6d9b6210 --- /dev/null +++ b/docs/standard/security/snippets/how-to-use-data-protection/framework/csharp/DataProtectionSample.csproj @@ -0,0 +1,42 @@ + + + + + Debug + AnyCPU + {9B14A2C4-4E4E-4A8E-9C3B-8F5F8D9C6A21} + Exe + DataProtectionSample + DataProtectionSample + v4.8 + 512 + true + + + AnyCPU + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + AnyCPU + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + + + + + + + diff --git a/samples/snippets/csharp/VS_Snippets_CLR/DPAPI-HowTO/cs/sample.cs b/docs/standard/security/snippets/how-to-use-data-protection/framework/csharp/sample.cs similarity index 88% rename from samples/snippets/csharp/VS_Snippets_CLR/DPAPI-HowTO/cs/sample.cs rename to docs/standard/security/snippets/how-to-use-data-protection/framework/csharp/sample.cs index 335f0103d116a..7f3d47a4acbb7 100644 --- a/samples/snippets/csharp/VS_Snippets_CLR/DPAPI-HowTO/cs/sample.cs +++ b/docs/standard/security/snippets/how-to-use-data-protection/framework/csharp/sample.cs @@ -1,14 +1,11 @@ -// -using System; +using System; using System.IO; using System.Text; using System.Security.Cryptography; public class MemoryProtectionSample { - public static void Main() => Run(); - - public static void Run() + public static void Main() { try { @@ -19,21 +16,21 @@ public static void Run() /////////////////////////////// // Create the original data to be encrypted (The data length should be a multiple of 16). - byte[] toEncrypt = UnicodeEncoding.ASCII.GetBytes("ThisIsSomeData16"); + byte[] toEncrypt = Encoding.ASCII.GetBytes("ThisIsSomeData16"); - Console.WriteLine($"Original data: {UnicodeEncoding.ASCII.GetString(toEncrypt)}"); + Console.WriteLine(value: $"Original data: {Encoding.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($"Encrypted data: {Encoding.ASCII.GetString(toEncrypt)}"); Console.WriteLine("Decrypting..."); // Decrypt the data in memory. DecryptInMemoryData(toEncrypt, MemoryProtectionScope.SameLogon); - Console.WriteLine($"Decrypted data: {UnicodeEncoding.ASCII.GetString(toEncrypt)}"); + Console.WriteLine($"Decrypted data: {Encoding.ASCII.GetString(toEncrypt)}"); /////////////////////////////// // @@ -42,7 +39,7 @@ public static void Run() /////////////////////////////// // Create the original data to be encrypted - toEncrypt = UnicodeEncoding.ASCII.GetBytes("This is some data of any length."); + toEncrypt = Encoding.ASCII.GetBytes("This is some data of any length."); // Create a file. FileStream fStream = new FileStream("Data.dat", FileMode.OpenOrCreate); @@ -51,7 +48,7 @@ public static void Run() byte[] entropy = CreateRandomEntropy(); Console.WriteLine(); - Console.WriteLine($"Original data: {UnicodeEncoding.ASCII.GetString(toEncrypt)}"); + Console.WriteLine($"Original data: {Encoding.ASCII.GetString(toEncrypt)}"); Console.WriteLine("Encrypting and writing to disk..."); // Encrypt a copy of the data to the stream. @@ -69,7 +66,7 @@ public static void Run() fStream.Close(); - Console.WriteLine($"Decrypted data: {UnicodeEncoding.ASCII.GetString(decryptData)}"); + Console.WriteLine($"Decrypted data: {Encoding.ASCII.GetString(decryptData)}"); } catch (Exception e) { @@ -172,4 +169,3 @@ public static byte[] DecryptDataFromStream(byte[] Entropy, DataProtectionScope S return outBuffer; } } -// diff --git a/docs/standard/security/snippets/how-to-use-data-protection/framework/csharp/snippets.5000.json b/docs/standard/security/snippets/how-to-use-data-protection/framework/csharp/snippets.5000.json new file mode 100644 index 0000000000000..da9ebf8da2f9d --- /dev/null +++ b/docs/standard/security/snippets/how-to-use-data-protection/framework/csharp/snippets.5000.json @@ -0,0 +1,3 @@ +{ + "host": "visualstudio" +} diff --git a/docs/standard/security/snippets/how-to-use-data-protection/framework/vb/DataProtectionSample.vbproj b/docs/standard/security/snippets/how-to-use-data-protection/framework/vb/DataProtectionSample.vbproj new file mode 100644 index 0000000000000..c40d75bd4b768 --- /dev/null +++ b/docs/standard/security/snippets/how-to-use-data-protection/framework/vb/DataProtectionSample.vbproj @@ -0,0 +1,56 @@ + + + + + Debug + AnyCPU + {A4B12E1F-3C6D-4B25-9E5B-2E7D3A9F1B04} + Exe + DataProtectionSample + DataProtectionSample + v4.8 + Console + DataProtectionSample.MemoryProtectionSample + 512 + true + On + Binary + Off + On + + + AnyCPU + true + full + true + true + bin\Debug\ + DataProtectionSample.xml + 42016,41999,42017,42018,42019,42032,42036,42020,42021,42022 + + + AnyCPU + pdbonly + false + true + true + bin\Release\ + DataProtectionSample.xml + 42016,41999,42017,42018,42019,42032,42036,42020,42021,42022 + + + + + + + + + + + + + + + + + diff --git a/samples/snippets/visualbasic/VS_Snippets_CLR/DPAPI-HowTO/vb/sample.vb b/docs/standard/security/snippets/how-to-use-data-protection/framework/vb/sample.vb similarity index 80% rename from samples/snippets/visualbasic/VS_Snippets_CLR/DPAPI-HowTO/vb/sample.vb rename to docs/standard/security/snippets/how-to-use-data-protection/framework/vb/sample.vb index 1b2ea95b3e31c..e954812dcd77c 100644 --- a/samples/snippets/visualbasic/VS_Snippets_CLR/DPAPI-HowTO/vb/sample.vb +++ b/docs/standard/security/snippets/how-to-use-data-protection/framework/vb/sample.vb @@ -1,42 +1,31 @@ -' -Imports System.IO +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") + Dim toEncrypt As Byte() = Encoding.ASCII.GetBytes("ThisIsSomeData16") - Console.WriteLine("Original data: " + UnicodeEncoding.ASCII.GetString(toEncrypt)) + Console.WriteLine("Original data: " + Encoding.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("Encrypted data: " + Encoding.ASCII.GetString(toEncrypt)) Console.WriteLine("Decrypting...") ' Decrypt the data in memory. DecryptInMemoryData(toEncrypt, MemoryProtectionScope.SameLogon) - Console.WriteLine("Decrypted data: " + UnicodeEncoding.ASCII.GetString(toEncrypt)) + Console.WriteLine("Decrypted data: " + Encoding.ASCII.GetString(toEncrypt)) '''''''''''''''''''''''''''''''''''' @@ -45,7 +34,7 @@ Public Module MemoryProtectionSample ' '''''''''''''''''''''''''''''''''''' ' Create the original data to be encrypted - toEncrypt = UnicodeEncoding.ASCII.GetBytes("This is some data of any length.") + toEncrypt = Encoding.ASCII.GetBytes("This is some data of any length.") ' Create a file. Dim fStream As New FileStream("Data.dat", FileMode.OpenOrCreate) @@ -54,7 +43,7 @@ Public Module MemoryProtectionSample Dim entropy As Byte() = CreateRandomEntropy() Console.WriteLine() - Console.WriteLine("Original data: " + UnicodeEncoding.ASCII.GetString(toEncrypt)) + Console.WriteLine("Original data: " + Encoding.ASCII.GetString(toEncrypt)) Console.WriteLine("Encrypting and writing to disk...") ' Encrypt a copy of the data to the stream. @@ -72,8 +61,7 @@ Public Module MemoryProtectionSample fStream.Close() - Console.WriteLine("Decrypted data: " + UnicodeEncoding.ASCII.GetString(decryptData)) - + Console.WriteLine("Decrypted data: " + Encoding.ASCII.GetString(decryptData)) Catch e As Exception Console.WriteLine("ERROR: " + e.Message) @@ -81,9 +69,7 @@ Public Module MemoryProtectionSample End Sub - - - Sub EncryptInMemoryData(ByVal Buffer() As Byte, ByVal Scope As MemoryProtectionScope) + Sub EncryptInMemoryData(Buffer() As Byte, Scope As MemoryProtectionScope) If Buffer Is Nothing Then Throw New ArgumentNullException("Buffer") End If @@ -96,8 +82,7 @@ Public Module MemoryProtectionSample End Sub - - Sub DecryptInMemoryData(ByVal Buffer() As Byte, ByVal Scope As MemoryProtectionScope) + Sub DecryptInMemoryData(Buffer() As Byte, Scope As MemoryProtectionScope) If Buffer Is Nothing Then Throw New ArgumentNullException("Buffer") End If @@ -110,7 +95,6 @@ Public Module MemoryProtectionSample End Sub - Function CreateRandomEntropy() As Byte() ' Create a byte array to hold the random value. Dim entropy(15) As Byte @@ -126,9 +110,7 @@ Public Module MemoryProtectionSample End Function 'CreateRandomEntropy - - - Function EncryptDataToStream(ByVal Buffer() As Byte, ByVal Entropy() As Byte, ByVal Scope As DataProtectionScope, ByVal S As Stream) As Integer + Function EncryptDataToStream(Buffer() As Byte, Entropy() As Byte, Scope As DataProtectionScope, S As Stream) As Integer If Buffer Is Nothing Then Throw New ArgumentNullException("Buffer") End If @@ -161,8 +143,7 @@ Public Module MemoryProtectionSample End Function 'EncryptDataToStream - - Function DecryptDataFromStream(ByVal Entropy() As Byte, ByVal Scope As DataProtectionScope, ByVal S As Stream, ByVal Length As Integer) As Byte() + Function DecryptDataFromStream(Entropy() As Byte, Scope As DataProtectionScope, S As Stream, Length As Integer) As Byte() If S Is Nothing Then Throw New ArgumentNullException("S") End If @@ -176,7 +157,6 @@ Public Module MemoryProtectionSample Throw New ArgumentException("Entropy") End If - Dim inBuffer(Length - 1) As Byte Dim outBuffer() As Byte @@ -194,4 +174,3 @@ Public Module MemoryProtectionSample End Function 'DecryptDataFromStream End Module 'MemoryProtectionSample -' diff --git a/docs/standard/security/snippets/how-to-use-data-protection/framework/vb/snippets.5000.json b/docs/standard/security/snippets/how-to-use-data-protection/framework/vb/snippets.5000.json new file mode 100644 index 0000000000000..da9ebf8da2f9d --- /dev/null +++ b/docs/standard/security/snippets/how-to-use-data-protection/framework/vb/snippets.5000.json @@ -0,0 +1,3 @@ +{ + "host": "visualstudio" +} diff --git a/docs/standard/security/snippets/how-to-use-data-protection/net/csharp/DataProtectionSample.csproj b/docs/standard/security/snippets/how-to-use-data-protection/net/csharp/DataProtectionSample.csproj new file mode 100644 index 0000000000000..a7c0dff8bc269 --- /dev/null +++ b/docs/standard/security/snippets/how-to-use-data-protection/net/csharp/DataProtectionSample.csproj @@ -0,0 +1,14 @@ + + + + Exe + net10.0-windows + enable + enable + + + + + + + diff --git a/docs/standard/security/snippets/how-to-use-data-protection/net/csharp/sample.cs b/docs/standard/security/snippets/how-to-use-data-protection/net/csharp/sample.cs new file mode 100644 index 0000000000000..3d8a584dac688 --- /dev/null +++ b/docs/standard/security/snippets/how-to-use-data-protection/net/csharp/sample.cs @@ -0,0 +1,90 @@ +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); +} diff --git a/docs/standard/security/snippets/how-to-use-data-protection/net/vb/DataProtectionSample.vbproj b/docs/standard/security/snippets/how-to-use-data-protection/net/vb/DataProtectionSample.vbproj new file mode 100644 index 0000000000000..c43bb9e43aaa3 --- /dev/null +++ b/docs/standard/security/snippets/how-to-use-data-protection/net/vb/DataProtectionSample.vbproj @@ -0,0 +1,13 @@ + + + + Exe + DataProtectionSample + net10.0-windows + + + + + + + diff --git a/docs/standard/security/snippets/how-to-use-data-protection/net/vb/sample.vb b/docs/standard/security/snippets/how-to-use-data-protection/net/vb/sample.vb new file mode 100644 index 0000000000000..c3ceb8624e597 --- /dev/null +++ b/docs/standard/security/snippets/how-to-use-data-protection/net/vb/sample.vb @@ -0,0 +1,90 @@ +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 diff --git a/samples/snippets/csharp/VS_Snippets_CLR/DPAPI-HowTO/cs/sample.csproj b/samples/snippets/csharp/VS_Snippets_CLR/DPAPI-HowTO/cs/sample.csproj deleted file mode 100644 index 18b78dcf3f1a5..0000000000000 --- a/samples/snippets/csharp/VS_Snippets_CLR/DPAPI-HowTO/cs/sample.csproj +++ /dev/null @@ -1,12 +0,0 @@ - - - - Exe - net461 - - - - - - - \ No newline at end of file From 7426efd878d13675dfd1cb8f266e5e8be45882a4 Mon Sep 17 00:00:00 2001 From: "Andy De George (from Dev Box)" Date: Wed, 22 Jul 2026 13:41:31 -0700 Subject: [PATCH 5/8] Edit pass --- .../security/how-to-use-data-protection.md | 28 ++++++++----------- 1 file changed, 12 insertions(+), 16 deletions(-) diff --git a/docs/standard/security/how-to-use-data-protection.md b/docs/standard/security/how-to-use-data-protection.md index 4ddd5373decad..50130a7be64b4 100644 --- a/docs/standard/security/how-to-use-data-protection.md +++ b/docs/standard/security/how-to-use-data-protection.md @@ -1,5 +1,5 @@ --- -title: "How to: Use Data Protection" +title: "How to use data protection" description: Learn how to use data protection by accessing the data protection API (DPAPI) in .NET. ms.date: 07/22/2026 ai-usage: ai-assisted @@ -18,16 +18,16 @@ helpviewer_keywords: - "data [.NET], encryption" ms.assetid: 606698b0-cb1a-42ca-beeb-0bea34205d20 --- -# How to: Use Data Protection +# How to use data protection > [!NOTE] > This article applies to Windows. > > For information about ASP.NET Core, see [ASP.NET Core Data Protection](/aspnet/core/security/data-protection/introduction). -.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. +.NET provides access to the data protection API (DPAPI), which lets you encrypt data using information from the current user account or computer. When you use the DPAPI, you avoid the difficult problem of explicitly generating and storing a cryptographic key. -Use the 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 enumeration for a detailed description of options. +Use the class to encrypt a copy of an array of bytes. You can specify that only the same user account can decrypt the data, or that any account on the computer can decrypt it. For a detailed description of options, see the enumeration. ## Encrypt data to a file or stream using data protection @@ -45,25 +45,21 @@ Use the class to encrypt a cop ## 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. +The following code example shows two forms of encryption and decryption. First, the code encrypts and then decrypts an in-memory array of bytes. Next, the code 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. -> [!NOTE] -> If you target .NET instead of .NET Framework, isn't available. The `EncryptInMemoryData` and `DecryptInMemoryData` methods rely on that API, so those methods don't compile on .NET. +> [!IMPORTANT] +> is only available for .NET Framework. is available on .NET and .NET Framework. ### [.NET Framework](#tab/net-framework) -To compile the sample: - -- Include a reference to `System.Security.dll`. - -This sample compiles and runs when targeting .NET Framework on Windows. To compile the sample, add a library reference to `System.Security.dll`. +This sample compiles and runs when you target .NET Framework on Windows. To compile the sample, add a library reference to `System.Security.dll`. :::code language="csharp" source="./snippets/how-to-use-data-protection/framework/csharp/sample.cs" id="FullSample"::: :::code language="vb" source="./snippets/how-to-use-data-protection/framework/vb/sample.vb"::: ### [.NET](#tab/net) -This sample compiles and runs when targeting .NET on Windows. To compile the sample, add [`System.Security.Cryptography.ProtectedData`](https://www.nuget.org/packages/System.Security.Cryptography.ProtectedData/) NuGet package. +This sample compiles and runs when you target .NET on Windows. To compile the sample, add the [`System.Security.Cryptography.ProtectedData`](https://www.nuget.org/packages/System.Security.Cryptography.ProtectedData/) NuGet package. :::code language="csharp" source="./snippets/how-to-use-data-protection/net/csharp/sample.cs"::: :::code language="vb" source="./snippets/how-to-use-data-protection/net/vb/sample.vb"::: @@ -72,9 +68,9 @@ This sample compiles and runs when targeting .NET on Windows. To compile the sam ## See also -- [Cryptography Model](cryptography-model.md) -- [Cryptographic Services](cryptographic-services.md) -- [Cross-Platform Cryptography](cross-platform-cryptography.md) +- [Cryptography model](cryptography-model.md) +- [Cryptographic services](cryptographic-services.md) +- [Cross-platform cryptography](cross-platform-cryptography.md) - - - [ASP.NET Core Data Protection](/aspnet/core/security/data-protection/introduction) From 96c59362705c9360722bb3ddb1e770c56eeb1229 Mon Sep 17 00:00:00 2001 From: "Andy De George (from Dev Box)" Date: Wed, 22 Jul 2026 13:46:03 -0700 Subject: [PATCH 6/8] Remove missed id --- docs/standard/security/how-to-use-data-protection.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/standard/security/how-to-use-data-protection.md b/docs/standard/security/how-to-use-data-protection.md index 50130a7be64b4..64c7bfb6835cc 100644 --- a/docs/standard/security/how-to-use-data-protection.md +++ b/docs/standard/security/how-to-use-data-protection.md @@ -54,7 +54,7 @@ The following code example shows two forms of encryption and decryption. First, This sample compiles and runs when you target .NET Framework on Windows. To compile the sample, add a library reference to `System.Security.dll`. -:::code language="csharp" source="./snippets/how-to-use-data-protection/framework/csharp/sample.cs" id="FullSample"::: +:::code language="csharp" source="./snippets/how-to-use-data-protection/framework/csharp/sample.cs"::: :::code language="vb" source="./snippets/how-to-use-data-protection/framework/vb/sample.vb"::: ### [.NET](#tab/net) From 322e36696bc7cd7a96b91bac8293d31932486efb Mon Sep 17 00:00:00 2001 From: "Andy De George (from Dev Box)" Date: Wed, 22 Jul 2026 14:04:58 -0700 Subject: [PATCH 7/8] Swap .net/.net framework; remove if applicable clause --- .../security/how-to-use-data-protection.md | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/docs/standard/security/how-to-use-data-protection.md b/docs/standard/security/how-to-use-data-protection.md index 64c7bfb6835cc..57adb8100beff 100644 --- a/docs/standard/security/how-to-use-data-protection.md +++ b/docs/standard/security/how-to-use-data-protection.md @@ -33,7 +33,7 @@ Use the class to encrypt a cop 1. Create random entropy. -2. Call the static method while passing an array of bytes to encrypt, the entropy, and (if applicable) the data protection scope. +2. Call the static 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. @@ -41,7 +41,7 @@ Use the class to encrypt a cop 1. Read the encrypted data from a file or stream. -2. Call the static method while passing an array of bytes to decrypt and (if applicable) the data protection scope. +2. Call the static method while passing an array of bytes to decrypt and the data protection scope. ## Example @@ -50,13 +50,6 @@ The following code example shows two forms of encryption and decryption. First, > [!IMPORTANT] > is only available for .NET Framework. is available on .NET and .NET Framework. -### [.NET Framework](#tab/net-framework) - -This sample compiles and runs when you target .NET Framework on Windows. To compile the sample, add a library reference to `System.Security.dll`. - -:::code language="csharp" source="./snippets/how-to-use-data-protection/framework/csharp/sample.cs"::: -:::code language="vb" source="./snippets/how-to-use-data-protection/framework/vb/sample.vb"::: - ### [.NET](#tab/net) This sample compiles and runs when you target .NET on Windows. To compile the sample, add the [`System.Security.Cryptography.ProtectedData`](https://www.nuget.org/packages/System.Security.Cryptography.ProtectedData/) NuGet package. @@ -64,6 +57,13 @@ This sample compiles and runs when you target .NET on Windows. To compile the sa :::code language="csharp" source="./snippets/how-to-use-data-protection/net/csharp/sample.cs"::: :::code language="vb" source="./snippets/how-to-use-data-protection/net/vb/sample.vb"::: +### [.NET Framework](#tab/net-framework) + +This sample compiles and runs when you target .NET Framework on Windows. To compile the sample, add a library reference to `System.Security.dll`. + +:::code language="csharp" source="./snippets/how-to-use-data-protection/framework/csharp/sample.cs"::: +:::code language="vb" source="./snippets/how-to-use-data-protection/framework/vb/sample.vb"::: + --- ## See also From e0708c411525afffaca9296f823d1706e4eedf7e Mon Sep 17 00:00:00 2001 From: "Andy De George (from Dev Box)" Date: Wed, 22 Jul 2026 14:06:29 -0700 Subject: [PATCH 8/8] Minor --- docs/standard/security/how-to-use-data-protection.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/standard/security/how-to-use-data-protection.md b/docs/standard/security/how-to-use-data-protection.md index 57adb8100beff..30a8d9c228cb1 100644 --- a/docs/standard/security/how-to-use-data-protection.md +++ b/docs/standard/security/how-to-use-data-protection.md @@ -59,7 +59,7 @@ This sample compiles and runs when you target .NET on Windows. To compile the sa ### [.NET Framework](#tab/net-framework) -This sample compiles and runs when you target .NET Framework on Windows. To compile the sample, add a library reference to `System.Security.dll`. +This sample compiles and runs when you target .NET Framework on Windows. To compile the sample, add reference to the `System.Security.dll` library. :::code language="csharp" source="./snippets/how-to-use-data-protection/framework/csharp/sample.cs"::: :::code language="vb" source="./snippets/how-to-use-data-protection/framework/vb/sample.vb":::