Decrypting PGP data with C# and VB.NET

This chapter illustrates OpenPGP decryption with C# and VB.NET examples.

In order to decrypt an OpenPGP encrypted file, we need the private key corresponding to the public key(s) it was encrypted with. Note that an OpenPGP archive may contain multiple files, although the most common scenario is only one file in an OpenPGP archive.

Another possibility is if the OpenPGP file was encrypted with a password and we shall use the same password to decrypt it.

List of examples


Appendix

A. Exception handling

1. Decrypting a file with a private key located in a file

This example demonstrates OpenPGP file decryption with a private key stored in a file. The private key password is also needed, in order for the key to be used.

The method DecryptFile returns the original file name of the extracted file.

C# example

using System;
using DidiSoft.Pgp;
 
public class DecryptDemo
{
 public void Demo()
 {
  // initialize the library
  PGPLib pgp = new PGPLib();
 
  string inputFileLocation = @"c:\INPUT.pgp";
  string privateKeyLocation = @"c:\private_key.asc";
  string privateKeyPassword = "key password";
  string outputFile = @"c:\Output.txt";
 
  // decrypt and obtain the original file name
  // of the decrypted file
  string originalFileName =
              pgp.DecryptFile(inputFileLocation,
                          privateKeyLocation,
                          privateKeyPassword,
                          outputFile);
 }
}

VB.NET example

Imports System
Imports DidiSoft.Pgp
 
Public Class DecryptDemo
 Public Sub Demo()
  ' create an instance of the library
  Dim pgp As New PGPLib()
 
  Dim inputFileLocation As String = "c:\INPUT.pgp"
  Dim privateKeyLocation As String = "c:\private_key.asc"
  Dim outputFile As String = "c:\Output.txt"
 
  ' decrypt and obtain the original file name
  Dim originalFileName As String
  originalFileName = pgp.DecryptFile(inputFileLocation , _
                                     privateKeyLocation , _
                                     "key password", _
                                      outputFile)
 End Sub
End Class

2. Decrypting a file with a private key located in a KeyStore

This example is equivalent to the above one, except that the private decryption key is stored in a KeyStore object. Keeping our private keys in a KeyStore gives us an extra layer of security.

C# example

using System;
using DidiSoft.Pgp;
 
public class DecryptDemo
{
 public void Demo()
 {
  // initialize the library
  PGPLib pgp = new PGPLib();
 
  // initialize the KeyStore
  KeyStore keyStore = KeyStore.OpenFile(@"c:\key.store", "my keystore password");
 
  string inputFileLocation = @"c:\INPUT.pgp";
  string privateKeyPassword = "key password";
  string outputFile = @"c:\Output.txt";
 
  string privateKeyPassword = "changeit";
 
  //decrypt and obtain the original file name
  string originalFileName = pgp.DecryptFile(inputFileLocation,
                                                        keyStore,
                                                        privateKeyPassword,
                                                        outputFile);
 }
}

VB.NET example

Imports System
Imports DidiSoft.Pgp
 
Public Class DecryptDemo
 Public Sub Demo()
  ' create an instance of the library
  Dim pgp As New PGPLib()
 
  ' initialize the KeyStore
  Dim keysStore As KeyStore = KeyStore.OpenFile("c:\key.store", "my keystore password")
 
  Dim inputFileLocation As String = "c:\INPUT.pgp"
  Dim privateKeyPassword As String = "key password"
  Dim outputFile As String = "c:\Output.txt"
 
  ' decrypt and obtain the original file name
  Dim originalFileName As String = _
               pgp.DecryptFile(inputFileLocation , _
                               keysStore, _
                               privateKeyPassword, _
                               outputFile)
 End Sub
End Class

3. Decrypting a String with a private key located in a file

Sometimes we may receive a string message and in that case, it is easier to decrypt it directly instead of writing it to a file before that. The example below shows how to achieve this:

C# example

using System;
using System.IO;
using DidiSoft.Pgp;
 
class DecryptString {
 public String Decrypt(String encryptedString)
 {
   // create an instance of the library
   PGPLib pgp = new PGPLib();
 
   String plainString =
     pgp.DecryptString(encryptedString,
		       new FileInfo(@"DataFiles\private.key"),
                       "private key password");
 
   return plainString;
 }
}

VB.NET example

Imports System
Imports System.IO
Imports DidiSoft.Pgp
 
Class DecryptString
 Public Shared Function Decrypt(ByVal encryptedString _
                               As String) As String
  ' create an instance of the library
  Dim pgp As New PGPLib()
 
  Dim plainString As String = _
    pgp.DecryptString(encryptedString, _
 		New FileInfo("DataFiles\private.key"), _
		"private key password")
 
  Return plainString
 End Function
End Class

4. Decrypting a String with a decryption key located in a KeyStore

The example below shows how to decrypt a string message when our private decryption key is stored in a KeyStore object.

C# example

using System;
using DidiSoft.Pgp;
using DidiSoft.Pgp.Exceptions;
 
class KeyStoreDecryptString
{
 public void Demo()
 {
  // initialize the key store
  KeyStore ks = new KeyStore(@"c:\key.store", "keystore password");
 
  try {
        // create an instance of the library
        PGPLib pgp = new PGPLib();
 
	// obtain encrypted string
	string encryptedString = ...
 
	string plainText = pgp.DecryptString(encryptedString, ks);
  }
  catch (WrongPrivateKeyException)
  {
	Console.WriteLine("No suitable dercyption key was found" +
                          " in this key store.");
  }
 }
}

VB.NET example

Imports System
Imports DidiSoft.Pgp
Imports DidiSoft.Pgp.Exceptions
 
Class KeyStoreDecryptString
 Public Sub Demo()
  ' initialize the key store
  Dim ks As KeyStore = KeyStore.OpenFile("c:\key.store", "my keystore password")
 
  Try
   ' create an instance of the library
   Dim pgp As New PGPLib()
 
   ' obtain enrypted string message
   Dim encryptedString As String = ...
 
   Dim plainText As String = pgp.DecryptString(encryptedString, ks)
  Catch generatedExceptionName As WrongPrivateKeyException
   Console.WriteLine("No suitable decryption key was found " + _
                     "in this key store.")
  End Try
 End Sub
End Class

5. Decrypting PGP encrypted input stream with a private key supplied as a stream

An important point in this example is that the decrypted data is written down on an output Stream. If afterwards, we wish to read the decrypted data, we have to create a stream for reading from the decrypted stream (for example we can supply a MemoryStream for the decryptedStream parameter and after decrypting create a new MemoryStream(decryptedStream.ToArray()).

C# example

using System;
using System.IO;
using DidiSoft.Pgp;
 
public class DecryptStreamDemo
{
 public Stream Decrypt()
 {
   // initialize the library
   PGPLib pgp = new PGPLib();
 
   MemoryStream decryptedOutput = new MemoryStream();
 
   //
   // Although here the data stream and the private key are file streams
   //  they can be any kind of stream
   //
   using (Stream dataFileStream = File.OpenRead(@"DataFiles\INPUT.pgp"))
   using (Stream privateKeyStream = File.OpenRead(@"DataFiles\private.key"))
   {
      string privateKeyPassword = "changeit";
 
      string originalFileName =
        pgp.DecryptStream(dataFileStream,
                          privateKeyStream,
                          privateKeyPassword,
                          decryptedOutput);
 
      Console.WriteLine("The original file name of the decrypted data was :" 
                        + originalFileName);
 
      //
      // Because the decryptedOutput stream Position is at the end of the stream,
      // we have to reinitialize it in order to be able to read it afterwards
      //
      decryptedOutput = new MemoryStream(decryptedOutput.ToArray());
      return decryptedOutput;
  }
 }
}

VB.NET example

Imports System
Imports System.IO
Imports DidiSoft.Pgp
 
Public Class DecryptStreamDemo
 Public Function Decrypt() As Stream
   ' initialize the library
   Dim pgp As New PGPLib()
 
   Dim decryptedOutput As New MemoryStream()
 
   '
   ' Although here the data stream and the private key are file streams
   '  they can be any kind of stream
   '
   Using dataFileStream As Stream = File.OpenRead("DataFiles\INPUT.pgp")
    Using privateKeyStream As Stream = File.OpenRead("DataFiles\private.key")
        Dim privateKeyPassword As String = "changeit"
 
        Dim originalFileName As String = _
                pgp.DecryptStream(dataFileStream, _
                                  privateKeyStream, privateKeyPassword, decryptedOutput)
 
        Console.WriteLine("The original file name of the decrypted data was :" + originalFileName)
 
        '
        ' Because the decryptedOutput stream Position is at the end of the stream,
        ' we have to reinitialize it in order to be able to read it afterwards
        '
        decryptedOutput = New MemoryStream(decryptedOutput.ToArray())
        Return decryptedOutput
   End Using
  End Using
 End Function
End Class

6. Decrypting PGP encrypted input stream with a private key located in a KeyStore

This example is equivalent to the above one, except that the private key is located in a KeyStore object.

C# example

using System;
using System.IO;
using DidiSoft.Pgp;
 
public class KeyStoreDecryptStream
{
 public void Demo()
 {
   // initialize the library
   PGPLib pgp = new PGPLib();
 
   // initialize the key store
   KeyStore kStore = KeyStore.OpenFile(@"c:\key.store", "my keystore password");
 
   MemoryStream decryptedOutput = new MemoryStream();
 
   //
   // Although here the data stream and the private key are file streams
   //  they can be any kind of stream
   //
   using (Stream dataFileStream = File.OpenRead(@"DataFiles\INPUT.pgp"))
   {
	string privateKeyPassword = "changeit";
 
	string originalFileName =
	  pgp.DecryptStream(dataFileStream,
			  kStore,
			  privateKeyPassword,
			  decryptedOutput);
 
	Console.WriteLine("The original file name of the decrypted data was :"
							+ originalFileName);
 
	//
	// Because the decryptedOutput stream Position is at the end of the stream,
	// we have to reinitialize it in order to be able to read it afterwards
	//
	decryptedOutput = new MemoryStream(decryptedOutput.ToArray());
   }
 }
}

VB.NET example

Imports System
Imports System.IO
Imports DidiSoft.Pgp
 
Public Class KeyStoreDecryptStream
 Public Sub Demo()
   ' initialize the library
   Dim pgp As New PGPLib()
 
   ' initialize the key store
   Dim kStore As KeyStore = KeyStore.OpenFile("c:\key.store", "my keystore password")
 
   Dim decryptedOutput As New MemoryStream()
 
   '
   ' Although here the data stream and the private key are file streams
   '  they can be any kind of stream
   '
   Using dataFileStream As Stream = File.OpenRead("DataFiles\INPUT.pgp")
    Dim privateKeyPassword As String = "changeit"
 
    Dim originalFileName As String = _
                  pgp.DecryptStream(dataFileStream, _
				kStore, _
				privateKeyPassword, _
				decryptedOutput)
 
    Console.WriteLine("The original file name of the decrypted data was :" + originalFileName)
 
    '
    ' Because the decryptedOutput stream Position is at the end of the stream,
    ' we have to reinitialize it in order to be able to read it afterwards
    '
    decryptedOutput = New MemoryStream(decryptedOutput.   
  End Using
 End Sub
End Class

7. Decrypting OpenPGP file contents to a folder when our private key is located in a file

This example demonstrates how to decrypt the contents of an OpenPGP archive into a folder. The DecryptFileInFolder method returns an array of full file paths of the decrypted file(s).

This method supports decrypting multi-file PGP archives, which is a feature supported by PGP Desktop version 9 and newer.

C# example

using System;
using DidiSoft.Pgp;
 
public class DecryptDemo
{
 public void Demo()
 {
  // initialize the library
  PGPLib pgp = new PGPLib();
 
  string inputFileLocation = @"c:\INPUT.pgp";
  string privateKeyLocation = @"c:\private_key.asc";
  string privateKeyPassword = "key password";
  string outputFolder = @"c:\Output";
 
  // decrypt and return array with full file paths
  // of the extracted file(s)
  string[] decryptedFileNames =
    pgp.DecryptFileInFolder(inputFileLocation,
		  privateKeyLocation,
		  privateKeyPassword,
		  outputFolder);
 
  // print the full path of the decrypted file(s)
  foreach (string filename in decryptedFileNames)
  {
    System.Console.WriteLine(filename);
  }
 }
}

VB.NET example

Imports System
Imports DidiSoft.Pgp
 
Public Class DecryptDemo
 Public Sub Demo()
  ' create an instance of the library
  Dim pgp As New PGPLib()
 
  Dim inputFileLocation As String = "c:\INPUT.pgp"
  Dim privateKeyLocation As String = "c:\private_key.asc"
  Dim outputFolder As String = "c:\Output"
 
  ' decrypt and return array with full file paths
  ' of the extracted file(s)
  Dim decryptedFileNames As String() = _
    pgp.DecryptFileInFolder(inputFileLocation, _
		privateKeyLocation, _
		"key password", _
		outputFolder)
 
  ' print the full path of the decrypted file(s)
  For Each filename As String In decryptedFileNames
      System.Console.WriteLine(filename)
  Next
 End Sub
End Class

(This method was introduced in version 1.6.2)

8. Decrypting OpenPGP file contents to a folder when our private key is located in a KeyStore

This example is equivalent to the above one, except that we have placed our private key in a KeyStore.

C# example

using System;
using DidiSoft.Pgp;
 
public class DecryptToDemo
{
 public void Demo()
 {
  // initialize the library
  PGPLib pgp = new PGPLib();
 
  // initialize the KeyStore
  KeyStore keyStore = KeyStore.OpenFile(@"c:\key.store", "my keystore password");
 
  string inputFileLocation = @"c:\INPUT.pgp";
  string privateKeyPassword = "key password";
  string outputFolder = @"c:\Output";
 
  // decrypt and return array with full file paths
  // of the extracted file(s)
  string[] decryptedFileNames =
    pgp.DecryptFileInFolder(inputFileLocation,
		  keyStore,
	          privateKeyPassword,
		  outputFolder);
 
  // print the full path of the decrypted file(s)
  foreach (string filename in decryptedFileNames)
  {
    System.Console.WriteLine(filename);
  }
 }
}

VB.NET example

Imports System
Imports DidiSoft.Pgp
 
Public Class DecryptToDemo
 Public Sub Demo()
  ' create an instance of the library
  Dim pgp As New PGPLib()
 
  ' initialize the KeyStore
  Dim keysStore As KeyStore = KeyStore.OpenFile("c:\key.store", "my keystore password")
 
  Dim inputFileLocation As String = "c:\INPUT.pgp"
  Dim outputFolder As String = "c:\Output"
 
  ' decrypt and return array with full file paths
  ' of the extracted file(s)
  Dim decryptedFileNames As String() = _
	  pgp.DecryptFileInFolder(inputFileLocation, _
			keysStore, _
			"key password", _
			outputFolder)
 
  ' print the full path of the decrypted file(s)
  For Each filename As String In decryptedFileNames
      System.Console.WriteLine(filename)
  Next
 End Sub
End Class

9. Decrypting password encrypted OpenPGP data

In this example, we specify the file name where the decrypted data will be extracted.

If the PGP encrypted file contains multiple files we can call the method PGPLib.DecryptPBEInFolder instead.

C# example

using System;
using DidiSoft.Pgp;
 
public class DecryptPBEDemo
{
 public void Demo()
 {
	// initialize the library
	PGPLib pgp = new PGPLib();
 
	string inputFileLocation = @"c:\INPUT.pgp";
	string password = "password";
	string decryptedOutput = @"c:\OUTPUT.txt";
 
	// decrypt and obtain the original file name
	string originalFileName =
	  pgp.DecryptFilePBE(inputFileLocation,
					  password,
					  decryptedOutput);
 }
}

VB.NET example

Imports System
Imports DidiSoft.Pgp
 
Public Class DecryptPBEDemo
 Public Sub Demo()
   ' create an instance of the library
   Dim pgp As New PGPLib()
 
   ' decrypt and obtain the original file name
   Dim originalFileName As String
   originalFileName = _
	  pgp.DecryptFilePBE("c:\INPUT.pgp", _
				"password", _
				"c:\OUTPUT.txt")
 End Sub
End Class

Appendix A. Exception Handling

All decryption methods throw two general exceptions: System.IO.IOException and DidiSoft.Pgp.PGPException.

For OpenPGP specific exception cases, we can try to check does the thrown exception belong to one of the defined exception subclasses from the DidiSoft.Pgp.Exceptions namespace. The example below illustrates the subclasses that we may expect.

C# example

using System;
using DidiSoft.Pgp;
using DidiSoft.Pgp.Exceptions;
 
public class ExceptionHandlingDemo
{
 public void Demo()
 {
  // initialize the library
  PGPLib pgp = new PGPLib();
 
  try 
  {
	pgp.Decrypt ...
  } catch (IOException e) {
  // error reading input or writing output
  } catch (PGPException e) {
   if (e is NonPGPDataException)
   {
   // the passed encrypted input is not a valid OpenPGP archive
   }
   else if (e is IntegrityCheckException)
   {
   // the passed encrypted input is corrupted
   }
   else if (e is FileIsPBEEncryptedException)
   {
   // the passed encrypted input is encrypted with a password,
   // but we try to decrypt it with a private key
   }
   else if (e is WrongPrivateKeyException)
   {
   // the encrypted input was encrypted with a different private key
   // than the provided one
   }
   else if (e is WrongPasswordException)
   {
   // the password for the provided private key is wrong
   }
   else
   {
   // general decryption error not among the above ones 
   }
  }
 }
}

VB.NET example

Imports System
Imports DidiSoft.Pgp
Imports DidiSoft.Pgp.Exceptions
 
Class ExceptionHandlingDemo
 Public Sub Demo()
  ' initialize the library
  Dim pgp As New PGPLib()
 
  Try
	pgp.Decrypt ...
  Catch e As IOException
  ' error reading input or writing output
  Catch e As PGPException
   If TypeOf e Is NonPGPDataException Then
   ' the passed encrypted input is not a valid OpenPGP archive
   ElseIf TypeOf e Is IntegrityCheckException Then
   ' the passed encrypted input is corrupted
   ElseIf TypeOf e Is FileIsPBEEncryptedException Then
   ' the passed encrypted input is encrypted with a password,
   ' but we try to decrypt it with a private key
   ElseIf TypeOf e Is WrongPrivateKeyException Then
   ' the encrypted input was encrypted with a different private key
   ' than the provided one
   ElseIf TypeOf e Is WrongPasswordException Then
   ' the password for the provided private key is wrong
   Else
   ' general decryption error not among the above ones 
   End If
  End Try
 End Sub
End Class

1-A. Decrypting a file with a private key located in a file asynchronously

Asynchronous decryption of OpenPGP data can be done with the PGPLibAsync class, that extends PGPLib.
Here the same parameters are used as those in the synchronous decryption, with an additional optional CancellationToken parameter at the end.

C# example

using System;
using System.Threading;
using DidiSoft.Pgp;
public class DecryptDemo
 public async void DecryptMethodAsync()
 {
  // File to be decrypted 
  string encryptedFile = "encrypted.pgp";
  // Usually our private key
  string privateKeyFile = "my_private_key.asc";
  // File where the decrypted data will be stored
  string decryptedOutputFile = "output.txt";
 
  // dummy cancelation token, in real world app 
  // this will be used to stop the process if needed
  CancellationToken token = default(CancellationToken);
 
  // Create an instance of the library
  PGPLibAsync pgp = new PGPLibAsync();
  // Password for the private key
  string privateKeyPassword = "my password";
  await pgp.DecryptFileAsync(encryptedFile, privateKeyFile, privateKeyPassword, decryptedOutputFile, token);
 }
}

The method DecryptFileAsync returns the internal file name label associated with the encrypted data. We can get that name by collecting the result in a variable:

using System;
string internalFileName = await pgp.DecryptFileAsync(encryptedFile, privateKeyFile, privateKeyPassword, decryptedOutputFile, token);

2-A. Async Decrypting a PGP file with a private key located in a KeyStore

In the code below the private key used for decrypting the OpenPGP encrypted file is located in a KeyStore.

C# example

using System;
using System.Threading;
using DidiSoft.Pgp;
 
public class DecryptDemoAsync
{
 public void Demo()
 {
  // initialize the key store
  KeyStore keyStore = new KeyStore(@"DataFiles\key.store", "changeit");
 
  // create an instance of the library
  PGPLibAsync pgp = new PGPLibAsync();
 
  String privateKeyPassword = "changeit";
 
  String dataFile = @"DataFiles\OUTPUT.pgp";
  String decryptedFile = @"DataFiles\OUTPUT.txt";
 
  // dummy cancelation token, in real world app 
  // this will be used to stop the process if needed
  CancellationToken token = default(CancellationToken);
 
  await pgp.DecryptFileAsync(dataFile, keyStore, privateKeyPassword, decryptedFile, token);
 }
}

Here we can also get the internal file name associated with the encrypted data by collecting the result of the DecryptFileAsync method.

String originalFileName =
                await pgp.DecryptFileAsync(dataFile, keyStore, privateKeyPassword, decryptedFile, token);

3-A. Async decryption of OpenPGP data available as String with a key in a file

The example below illustrates how to asynchronously decrypt an OpenPGP ASCII armored message available as string. This method is convenient if the decrypted data is relatively short and we need it also as string

C# example

using System;
using System.Threading;
using DidiSoft.Pgp;
 
public class DecryptString {
        public async Task DemoDecryptAsync(String encryptedString)
        {
            PGPLibAsync pgp = new PGPLibAsync();
            string privateKeypassword = "changeit";
            string privateKeyFileName = @"DataFiles\private.key";
            string plainString = await pgp.DecryptStringAsync(encryptedString,
                                                    privateKeyFileName,
                                                    privateKeypassword);
            return plainString;
        }
}

Of course here we can also pass a CancelationToken if needed.

CancellationToken token = default(CancellationToken);
string plainString = await pgp.DecryptStringAsync(encryptedString,
                                                  privateKeyFileName,
                                                  privateKeypassword,
                                                  token);

4. Async Decrypting a String with key in a KeyStore

The PGPLibAsync class can also decrypt asynchronously OpenPGP data encrypted as String with a private key from a KeyStore. In the sample code below, the encrypted data is hardcoded for the sake of the example in the OpenPGP ASCII armored format.

C# example

using System;
using DidiSoft.Pgp;
using DidiSoft.Pgp.Exceptions;
 
class KeyStoreDecryptString
{
 public async void Demo()
 {
 // initialize the key store
 KeyStore ks = new KeyStore(@"DataFiles\key.store", "changeit");
 
 try
 {
  // create an instance of the library
  PGPLibAsync pgp = new PGPLibAsync();
 
  string CrLf = "\r\n";
  // Hello World - enrypted
  string encryptedString =
  "-----BEGIN PGP MESSAGE-----" + CrLf +
  "Version: 1.0" + CrLf +
  "" + CrLf +
  "hQEOA/64kyVg6gZbEAP/XW9Gkt9yYsIH+W+EF1lmlGPtGCDP6nSDwx9xoC+SNW6X" + CrLf +
  "bHLKG2faxzGSjN8jMWArald+6ka/r7OSoh41qSgZgkkigpmpMb3ogIuw6TFoDwGv" + CrLf +
  "F1bFnXcl0MP3E8RDhMVLrqElkoUPRYFlao3H1OWtsEoUK6C2xtPCsDKP9+lLLPsD" + CrLf +
  "/3ZaEvtyaZk16obAT9IhEpFjroT72MYpcwHeAVYledXQHhCflinhkl0P6NvYUYlC" + CrLf +
  "yQdwlNgzSwYizegArRf3scrwnYjd7HtHWu3+orkase8OSp8Ikx9RmWVDX3DqSVHf" + CrLf +
  "ZqYdAUQS7Lo+45PVTMGGVR7ZdwxZbED9qp+yBBoVzXIAySe7UIydiELMA0rxlm2X" + CrLf +
  "ybdVYWtaX3H80ViMEUQAwTZz/wD2fqlBXVw=" + CrLf +
  "=MPJ2" + CrLf +
  "-----END PGP MESSAGE-----";
 
  string plainText = await pgp.DecryptStringAsync(encryptedString, ks, "changeit");
 }
 catch (DidiSoft.Pgp.Exceptions.WrongPrivateKeyException)
 {
	Console.WriteLine("No suitable deryption key was found in this key store.");
 }
}
}

5-A. Decrypting OpenPGP encrypted input Stream with a key from a Stream

This is example provides a demo method that returns a decrypted Stream, that is ready for reading.

Although in this example, the private decryption key is provided as Stream, it can also be provided as String variable (in an overloaded version). This would be suitable for example if we are storing our keys in a Cloud Key Vault (a sample helper class illustrating how to store OpenPGP keys in Azure key Vault can be seen here: https://github.com/didisoft/Azure-Pgp-Function-App/blob/main/EncryptBlobPgp/VaultKeyStorage.cs

C# example

using System.Threading.Tasks;
using System.IO;
using DidiSoft.Pgp;
 
public class DecryptStreamAsync
{
 public async Task Demo()
 {
  // initialize the library
  PGPLibAsync pgp = new PGPLibAsync();
 
  MemoryStream decryptedOutput = new MemoryStream();
  //
  // Although here the data stream and the private key are file streams
  //  they can be any kind of stream
  //
  using (Stream dataFileStream = File.OpenRead(@"DataFiles\INPUT.pgp"))
  using (Stream privateKeyStream = File.OpenRead(@"DataFiles\private.key"))
  {
	string privateKeyPassword = "changeit";
 
	string originalFileName =
	  await pgp.DecryptStreamAsync(dataFileStream,
				  privateKeyStream,
				  privateKeyPassword,
				  decryptedOutput);
 
	Console.WriteLine("The original file name of the decrypted data was :"
						+ originalFileName);
 
	//
	// Because the decryptedOutput stream Position is at the end of the stream,
	// we have to reinitialize it in order to be able to read it afterwards
	decryptedOutput.Position = 0;
	return decryptedOutput;
  }
 }
}

A CancellationToken can be provided as well as a last parameter to the DecryptStreamAsync method.

6-A. Decrypting OpenPGP encrypted Stream with a key from a KeyStore

In the example below we provide the password of a private key contained in a KeyStore and we assume that this key can decrypt the input encrypted data.

In more advanced scenarios, where we have multiple private keys in the KeyStore, we should check first which one of them will match the encrypted data with the help of PGPInspectLib.

C# example

using System;
using System.IO;
using DidiSoft.Pgp;
 
public class KeyStoreDecryptStream
{
 public async Task DemoDecrypt()
 {
 // initialize the library
 PGPLibAsync pgp = new PGPLibAsync();
 
 // initialize the key store
 KeyStore kStore = new KeyStore(@"DataFiles\key.store", "changeit");
 
 MemoryStream decryptedOutput = new MemoryStream();
 
 // Although here the data stream and the private key are file streams
 //  they can be any kind of stream
 using (Stream dataFileStream = File.OpenRead(@"DataFiles\INPUT.pgp"))
 {
	string privateKeyPassword = "changeit";
 
	await pgp.DecryptStreamAsync(dataFileStream,
				  kStore,
				  privateKeyPassword,
				  decryptedOutput);
 
	//
	// Because the decryptedOutput stream Position is at the end of the stream,
	// we have to reinitialize it in order to be able to read it afterwards
	//
	decryptedOutput.Position = 0;
	return decryptedOutput;
  }
 }
}

7-A. Async decryption of PGP file to a folder with key in a file

PGP archives containing multiple files, can be decrypted with the methods DecryptFileInFolderAsync and DecryptStreamInFolderAsync provided by the PGPLibAsync class.

The sample code below illustrates how to decrypt those files contained in a single .pgp archive into a specified folder.

C# example

using System;
using System.Threading;
using DidiSoft.Pgp;
 
public class DecryptDemo
{
 public async void Demo()
 {
  // initialize the library
  PGPLibAsync pgp = new PGPLibAsync();
 
  string inputFileLocation = @"c:\INPUT.pgp";
  string privateKeyLocation = @"c:\private_key.asc";
  string privateKeyPassword = "key password";
  string outputFolder = @"c:\Output";
 
  CancellationToken token = default(CancellationToken);
 
  // decrypt and return array with full file paths
  // of the extracted file(s)
  string[] decryptedFileNames =
    await pgp.DecryptFileInFolderAsync(inputFileLocation,
		  privateKeyLocation,
		  privateKeyPassword,
		  outputFolder,
                  token);
 
  // print the full path of the decrypted file(s)
  foreach (string filename in decryptedFileNames)
  {
    System.Console.WriteLine(filename);
  }
 }
}

VB.NET example
(available as of version 1.9.4)

8. Async decryption of PGP file into a folder with key located in a KeyStore

In this example our private key in a KeyStore. As in the sample above, a Cancellation token can be provided as last parameter.

C# example

using System;
using System.Threading;
using DidiSoft.Pgp;
 
public class DecryptToDemo
{
 public async void Demo()
 {
  // initialize the library
  PGPLibAsync pgp = new PGPLibAsync();
 
  // initialize the KeyStore
  KeyStore keyStore = KeyStore.OpenFile(@"c:\key.store", "my keystore password");
 
  string inputFileLocation = @"c:\INPUT.pgp";
  string privateKeyPassword = "key password";
  string outputFolder = @"c:\Output";
 
  // decrypt and return array with full file paths
  // of the extracted file(s)
  string[] decryptedFileNames =
    await pgp.DecryptFileInFolder(inputFileLocation,
		  keyStore,
	          privateKeyPassword,
		  outputFolder);
 
  // print the full path of the decrypted file(s)
  foreach (string filename in decryptedFileNames)
  {
    System.Console.WriteLine(filename);
  }
 }
}

VB.NET example

Imports System
Imports DidiSoft.Pgp
 
Public Class DecryptToDemo
 Public Sub Demo()
  ' create an instance of the library
  Dim pgp As New PGPLib()
 
  ' initialize the KeyStore
  Dim keysStore As KeyStore = KeyStore.OpenFile("c:\key.store", "my keystore password")
 
  Dim inputFileLocation As String = "c:\INPUT.pgp"
  Dim outputFolder As String = "c:\Output"
 
  ' decrypt and return array with full file paths
  ' of the extracted file(s)
  Dim decryptedFileNames As String() = _
	  pgp.DecryptFileInFolder(inputFileLocation, _
			keysStore, _
			"key password", _
			outputFolder)
 
  ' print the full path of the decrypted file(s)
  For Each filename As String In decryptedFileNames
      System.Console.WriteLine(filename)
  Next
 End Sub
End Class

 

Summary

This chapter presented examples illustrating the decryption of OpenPGP encrypted files. The decryption of files, string messages, and stream content was shown.

From here you can continue to the chapters for verification of OpenPGP signed data and decrypting and verifying one pass signed archives.

You may also be interested in analyzing the contents of an OpenPGP archive before actually extracting it.

Methods used:

PGPLib.DecryptFile Decripts a .pgp file that contains one encrypted file
PGPLib.DecryptTo Decripts a .pgp file that contains one or multiple files
PGPLib.DecryptStream Decripts an OpenPGP encrypted Stream
PGPLib.DecryptString Decripts an OpenPGP encrypted String message
PGPLib.DecryptFilePBE Decripts a .pgp file that was encrypted with a password