Skip to content

Commit

Permalink
Fix a bug in the encrypt sample, that was causing the decrypt to fail (
Browse files Browse the repository at this point in the history
…#23816)

* Fix a bug in the encrypt sample, that was causing the decrypt to fail

* Apply suggestions from code review

Co-authored-by: Youssef Victor <youssefvictor00@gmail.com>

* Apply suggestions from code review

* Apply suggestions from code review

* Corrected updated names

* Addressed feedback from peer review

* Use explicit scoping of disposable implementations

Co-authored-by: Youssef Victor <youssefvictor00@gmail.com>
  • Loading branch information
IEvangelist and Youssef1313 authored Apr 20, 2021
1 parent 0979dfc commit dfa6277
Show file tree
Hide file tree
Showing 10 changed files with 113 additions and 114 deletions.
8 changes: 4 additions & 4 deletions docs/standard/security/decrypting-data.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
---
title: "Decrypting data"
description: Learn how to decrypt data in .NET, using a symmetric algorithm or an asymmetric algorithm.
ms.date: 03/22/2021
ms.date: 04/19/2021
dev_langs:
- "csharp"
- "vb"
Expand All @@ -21,18 +21,18 @@ Decryption is the reverse operation of encryption. For secret-key encryption, yo

The decryption of data encrypted with symmetric algorithms is similar to the process used to encrypt data with symmetric algorithms. The <xref:System.Security.Cryptography.CryptoStream> class is used with symmetric cryptography classes provided by .NET to decrypt data read from any managed stream object.

The following example illustrates how to create a new instance of the default implementation class for the <xref:System.Security.Cryptography.Aes> algorithm. The instance is used to perform decryption on a <xref:System.Security.Cryptography.CryptoStream> object. This example first creates a new instance of the <xref:System.Security.Cryptography.Aes> implementation class. It reads the initialization vector (IV) value from a managed stream variable, `myStream`. Next it instantiates a <xref:System.Security.Cryptography.CryptoStream> object and initializes it to the value of the `myStream` instance. The <xref:System.Security.Cryptography.SymmetricAlgorithm.CreateDecryptor%2A?displayProperty=nameWithType> method from the <xref:System.Security.Cryptography.Aes> instance is passed the IV value and the same key that was used for encryption.
The following example illustrates how to create a new instance of the default implementation class for the <xref:System.Security.Cryptography.Aes> algorithm. The instance is used to perform decryption on a <xref:System.Security.Cryptography.CryptoStream> object. This example first creates a new instance of the <xref:System.Security.Cryptography.Aes> implementation class. It reads the initialization vector (IV) value from a managed stream variable, `fileStream`. Next it instantiates a <xref:System.Security.Cryptography.CryptoStream> object and initializes it to the value of the `fileStream` instance. The <xref:System.Security.Cryptography.SymmetricAlgorithm.CreateDecryptor%2A?displayProperty=nameWithType> method from the <xref:System.Security.Cryptography.Aes> instance is passed the IV value and the same key that was used for encryption.

```vb
Dim aes As Aes = Aes.Create()
Dim cryptStream As New CryptoStream(
myStream, aes.CreateDecryptor(key, iv), CryptoStreamMode.Read)
fileStream, aes.CreateDecryptor(key, iv), CryptoStreamMode.Read)
```

```csharp
Aes aes = Aes.Create();
CryptoStream cryptStream = new CryptoStream(
myStream, aes.CreateDecryptor(key, iv), CryptoStreamMode.Read);
fileStream, aes.CreateDecryptor(key, iv), CryptoStreamMode.Read);
```

The following example shows the entire process of creating a stream, decrypting the stream, reading from the stream, and closing the streams. A file stream object is created that reads a file named *TestData.txt*. The file stream is then decrypted using the **CryptoStream** class and the **Aes** class. This example specifies key value that is used in the symmetric encryption example for [Encrypting Data](encrypting-data.md). It does not show the code needed to encrypt and transfer these values.
Expand Down
8 changes: 4 additions & 4 deletions docs/standard/security/encrypting-data.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
---
title: "Encrypting data"
description: Learn how to encrypt data in .NET, using a symmetric algorithm or an asymmetric algorithm.
ms.date: 03/22/2021
ms.date: 04/16/2021
dev_langs:
- "csharp"
- "vb"
Expand All @@ -21,18 +21,18 @@ Symmetric encryption and asymmetric encryption are performed using different pro

The managed symmetric cryptography classes are used with a special stream class called a <xref:System.Security.Cryptography.CryptoStream> that encrypts data read into the stream. The **CryptoStream** class is initialized with a managed stream class, a class that implements the <xref:System.Security.Cryptography.ICryptoTransform> interface (created from a class that implements a cryptographic algorithm), and a <xref:System.Security.Cryptography.CryptoStreamMode> enumeration that describes the type of access permitted to the **CryptoStream**. The **CryptoStream** class can be initialized using any class that derives from the <xref:System.IO.Stream> class, including <xref:System.IO.FileStream>, <xref:System.IO.MemoryStream>, and <xref:System.Net.Sockets.NetworkStream>. Using these classes, you can perform symmetric encryption on a variety of stream objects.

The following example illustrates how to create a new instance of the default implementation class for the <xref:System.Security.Cryptography.Aes> algorithm. The instance is used to perform encryption on a **CryptoStream** class. In this example, the **CryptoStream** is initialized with a stream object called `myStream` that can be any type of managed stream. The **CreateEncryptor** method from the **Aes** class is passed the key and IV that are used for encryption. In this case, the default key and IV generated from `aes` are used.
The following example illustrates how to create a new instance of the default implementation class for the <xref:System.Security.Cryptography.Aes> algorithm. The instance is used to perform encryption on a **CryptoStream** class. In this example, the **CryptoStream** is initialized with a stream object called `fileStream` that can be any type of managed stream. The **CreateEncryptor** method from the **Aes** class is passed the key and IV that are used for encryption. In this case, the default key and IV generated from `aes` are used.

```vb
Dim aes As Aes = Aes.Create()
Dim cryptStream As New CryptoStream(
myStream, aes.CreateEncryptor(key, iv), CryptoStreamMode.Write)
fileStream, aes.CreateEncryptor(key, iv), CryptoStreamMode.Write)
```

```csharp
Aes aes = Aes.Create();
CryptoStream cryptStream = new CryptoStream(
myStream, aes.CreateEncryptor(key, iv), CryptoStreamMode.Write);
fileStream, aes.CreateEncryptor(key, iv), CryptoStreamMode.Write);
```

After this code is executed, any data written to the **CryptoStream** object is encrypted using the AES algorithm.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,43 +2,45 @@
using System.IO;
using System.Security.Cryptography;

public class DecryptExample
try
{
public static void Main(string[] args)
using (FileStream fileStream = new("TestData.txt", FileMode.Open))
{
//Decryption key must be the same value that was used
//to encrypt the stream.
byte[] key = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16 };

try
using (Aes aes = Aes.Create())
{
//Create a file stream.
using FileStream myStream = new FileStream("TestData.txt", FileMode.Open);

//Create a new instance of the default Aes implementation class
using Aes aes = Aes.Create();

//Reads IV value from beginning of the file.
byte[] iv = new byte[aes.IV.Length];
myStream.Read(iv, 0, iv.Length);
int numBytesToRead = aes.IV.Length;
int numBytesRead = 0;
while (numBytesToRead > 0)
{
int n = fileStream.Read(iv, numBytesRead, numBytesToRead);
if (n == 0) break;

//Create a CryptoStream, pass it the file stream, and decrypt
//it with the Aes class using the key and IV.
using CryptoStream cryptStream = new CryptoStream(
myStream,
aes.CreateDecryptor(key, iv),
CryptoStreamMode.Read);
numBytesRead += n;
numBytesToRead -= n;
}

//Read the stream.
using StreamReader sReader = new StreamReader(cryptStream);
byte[] key =
{
0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
0x09, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16
};

//Display the message.
Console.WriteLine("The decrypted original message: {0}", sReader.ReadToEnd());
}
catch
{
Console.WriteLine("The decryption failed.");
throw;
using (CryptoStream cryptoStream = new(
fileStream,
aes.CreateDecryptor(key, iv),
CryptoStreamMode.Read))
{
using (StreamReader decryptReader = new(cryptoStream))
{
string decryptedMessage = await decryptReader.ReadToEndAsync();
Console.WriteLine($"The decrypted original message: {decryptedMessage}");
}
}
}
}
}
catch (Exception ex)
{
Console.WriteLine($"The decryption failed. {ex}");
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp3.1</TargetFramework>
<TargetFramework>net5.0</TargetFramework>
</PropertyGroup>

</Project>
38 changes: 24 additions & 14 deletions docs/standard/security/snippets/decrypting-data/vb/aes-decrypt.vb
Original file line number Diff line number Diff line change
Expand Up @@ -4,30 +4,40 @@ Imports System.Security.Cryptography

Module Module1
Sub Main()
'Decryption key must be the same value that was used
'to encrypt the stream.
' Decryption key must be the same value that was used
' to encrypt the stream.
Dim key As Byte() = {&H1, &H2, &H3, &H4, &H5, &H6, &H7, &H8, &H9, &H10, &H11, &H12, &H13, &H14, &H15, &H16}

Try
'Create a file stream.
Using myStream As FileStream = New FileStream("TestData.txt", FileMode.Open)
' Create a file stream.
Using fileStream As New FileStream("TestData.txt", FileMode.Open)

'Create a new instance of the default Aes implementation class
' Create a new instance of the default Aes implementation class
Using aes As Aes = Aes.Create()

'Reads IV value from beginning of the file.
' Reads IV value from beginning of the file.
Dim iv As Byte() = New Byte(aes.IV.Length - 1) {}
myStream.Read(iv, 0, iv.Length)
Dim numBytesToRead As Integer = CType(aes.IV.Length, Integer)
Dim numBytesRead As Integer = 0

'Create an instance of the CryptoStream class, pass it the file stream, and decrypt
'it with the Rijndael class using the key and IV.
Using cryptStream As New CryptoStream(myStream, aes.CreateDecryptor(key, iv), CryptoStreamMode.Read)
While (numBytesToRead > 0)
Dim n As Integer = fileStream.Read(iv, numBytesRead, numBytesToRead)
If n = 0 Then
Exit While
End If
numBytesRead += n
numBytesToRead -= n
End While

'Read the stream.
Using sReader As New StreamReader(cryptStream)
' Create an instance of the CryptoStream class, pass it the file stream, and decrypt
' it with the Rijndael class using the key and IV.
Using cryptoStream As New CryptoStream(fileStream, aes.CreateDecryptor(key, iv), CryptoStreamMode.Read)

'Display the message.
Console.WriteLine("The decrypted original message: {0}", sReader.ReadToEnd())
' Read the stream.
Using decryptReader As New StreamReader(cryptoStream)

' Display the message.
Console.WriteLine($"The decrypted original message: {decryptReader.ReadToEnd()}")
End Using
End Using
End Using
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp3.1</TargetFramework>
<TargetFramework>net5.0</TargetFramework>
</PropertyGroup>

</Project>
Original file line number Diff line number Diff line change
Expand Up @@ -2,54 +2,38 @@
using System.IO;
using System.Security.Cryptography;

public class EncryptExample
try
{
public static void Main(string[] args)
using (FileStream fileStream = new("TestData.txt", FileMode.OpenOrCreate))
{
//Encryption key used to encrypt the stream.
//The same value must be used to encrypt and decrypt the stream.
byte[] key = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16 };

try
using (Aes aes = Aes.Create())
{
//Create a file stream
using FileStream myStream = new FileStream("TestData.txt", FileMode.OpenOrCreate);

//Create a new instance of the default Aes implementation class
// and configure encryption key.
using Aes aes = Aes.Create();
byte[] key =
{
0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
0x09, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16
};
aes.Key = key;

//Stores IV at the beginning of the file.
//This information will be used for decryption.
byte[] iv = aes.IV;
myStream.Write(iv, 0, iv.Length);
fileStream.Write(iv, 0, iv.Length);

//Create a CryptoStream, pass it the FileStream, and encrypt
//it with the Aes class.
using CryptoStream cryptStream = new CryptoStream(
myStream,
using (CryptoStream cryptoStream = new(
fileStream,
aes.CreateEncryptor(),
CryptoStreamMode.Write);

//Create a StreamWriter for easy writing to the
//file stream.
using StreamWriter sWriter = new StreamWriter(cryptStream);

//Write to the stream.
sWriter.WriteLine("Hello World!");

cryptStream.FlushFinalBlock();

//Inform the user that the message was written
//to the stream.
Console.WriteLine("The file was encrypted.");
}
catch
{
//Inform the user that an exception was raised.
Console.WriteLine("The encryption failed.");
throw;
CryptoStreamMode.Write))
{
using (StreamWriter encryptWriter = new(cryptoStream))
{
encryptWriter.WriteLine("Hello World!");
}
}
}
}

Console.WriteLine("The file was encrypted.");
}
catch (Exception ex)
{
Console.WriteLine($"The encryption failed. {ex}");
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp3.1</TargetFramework>
<TargetFramework>net5.0</TargetFramework>
</PropertyGroup>

</Project>
39 changes: 21 additions & 18 deletions docs/standard/security/snippets/encrypting-data/vb/aes-encrypt.vb
Original file line number Diff line number Diff line change
Expand Up @@ -4,33 +4,36 @@ Imports System.Security.Cryptography

Module Module1
Sub Main()
'Encryption key used to encrypt the stream.
'The same value must be used to encrypt and decrypt the stream.
Dim key As Byte() = {&H1, &H2, &H3, &H4, &H5, &H6, &H7, &H8, &H9, &H10, &H11, &H12, &H13, &H14, &H15, &H16}

Try
'Create a file stream
Using myStream As FileStream = New FileStream("TestData.txt", FileMode.OpenOrCreate)
' Create a file stream
Using fileStream As New FileStream("TestData.txt", FileMode.OpenOrCreate)

'Create a new instance of the default Aes implementation class
' and configure encryption key.
' Create a new instance of the default Aes implementation class
' and configure encryption key.
Using aes As Aes = Aes.Create()
'Encryption key used to encrypt the stream.
'The same value must be used to encrypt and decrypt the stream.
Dim key As Byte() = {
&H1, &H2, &H3, &H4, &H5, &H6, &H7, &H8,
&H9, &H10, &H11, &H12, &H13, &H14, &H15, &H16
}

aes.Key = key

'Stores IV at the beginning of the file.
'This information will be used for decryption.
' Stores IV at the beginning of the file.
' This information will be used for decryption.
Dim iv As Byte() = aes.IV
myStream.Write(iv, 0, iv.Length)
fileStream.Write(iv, 0, iv.Length)

'Create a CryptoStream, pass it the FileStream, and encrypt
'it with the Aes class.
Using cryptStream As New CryptoStream(myStream, aes.CreateEncryptor(), CryptoStreamMode.Write)
' Create a CryptoStream, pass it the FileStream, and encrypt
' it with the Aes class.
Using cryptoStream As New CryptoStream(fileStream, aes.CreateEncryptor(), CryptoStreamMode.Write)

'Create a StreamWriter for easy writing to the
'file stream.
Using sWriter As New StreamWriter(cryptStream)
' Create a StreamWriter for easy writing to the
' file stream.
Using sWriter As New StreamWriter(cryptoStream)

'Write to the stream.
'Write to the stream.
sWriter.WriteLine("Hello World!")
End Using
End Using
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp3.1</TargetFramework>
<TargetFramework>net5.0</TargetFramework>
</PropertyGroup>

</Project>

0 comments on commit dfa6277

Please sign in to comment.