PGP encryption in C# and VB.NET

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

What do we need?
In order to encrypt a file we usually need the public key(s) of the recipient(s).
There is also an option to encrypt with a password.

Filename extension
The common file name extension for OpenPGP encrypted files is .pgp

Additional parameters
The encrypt methods provided by the library have two additional parameters that reflect the encryption output: asciiArmor and withIntegrityCheck.

  • asciiArmor specifies the format of the result file:
    – when true the file is in ASCII armored text form (Operating System neutral form, suitable for Email attachments)
    – when false the output file is in a binary format
  • withIntegrityCheck specifies if additional integrity check information is appended to the encrypted file. For compatibility with GnuPG 2.2.8 and above, it must be true.

List of examples

Encrypting a file
1. with a public key located in a file | Async
2. with a public key located in a KeyStore | Async

Encrypting a String

3. with a public key located in a file | Async
4. with a public key located in a KeyStore | Async

Encrypting a Stream

5. with a key provided as Stream | Async
6. with a key located in a KeyStore | Async

Multiple recipients

7. Encrypting for multiple recipients | Async
8. Encrypting for multiple recipients with a KeyStore | Async

Multiple files

9. Encrypting multiple files into a single archive | Async
10. Encrypting multiple files with keys in a KeyStore | Async

OpenPGP password encryption

11. Encrypting with a password

Appendix

A. Exception Handling

1. Encrypt a file with recipient’s public key located in a file

This example demonstrates OpenPGP file encryption, providing public key stored directly in a file.

C# example

using System.IO;
using DidiSoft.Pgp;
 
class EncryptDemo {
 public void Demo() {
     // create an instance of the library
     PGPLib pgp = new PGPLib();
 
     // specify should the output be ASCII or binary
     bool asciiArmor = false;
     // should additional integrity information be added
     // set to true for compatibility with GnuPG 2.2.8+
     bool withIntegrityCheck = false;
 
     pgp.EncryptFile(@"C:\Test\INPUT.txt",
                     @"C:\Test\public_key.asc",
                     @"C:\Test\OUTPUT.pgp",
                     asciiArmor,
                     withIntegrityCheck);
 }
}

VB.NET example

Imports System.IO
Imports DidiSoft.Pgp
 
Class EncryptDemo
 Public Sub Demo()
     ' create an instance of the library
     Dim pgp As New PGPLib()
 
     ' specify should the output be ASCII or binary
     Dim asciiArmor As Boolean = False
     ' should additional integrity information be added   
     ' set to true for compatibility with GnuPG 2.2.8+
     Dim withIntegrityCheck As Boolean = False
 
     pgp.EncryptFile("C:\Test\INPUT.txt", _
                     "C:\Test\public_key.asc", _
                     "C:\Test\OUTPUT.pgp", _
                     asciiArmor, _
                     withIntegrityCheck)
 End Sub
End Class

2. Encrypt a file with recipient’s public key located in a KeyStore file

Storing our partners’ public keys in a KeyStore gives us one extra layer of security. For example how to import keys in a KeyStore see Import key ring in a KeyStore.

This sample shows how to encrypt a file with a public key stored in a Key store

C# example

using System;
using DidiSoft.Pgp;
 
public class KeyStoreEncryptFile
{
 public static void Demo()
 {
     // initialize the key store
     KeyStore keyStore = new KeyStore(@"DataFiles\key.store", "keystore passphrase");
     // create an instance of the library
     PGPLib pgp = new PGPLib();
 
     String publicKeyUserId = "support@didisoft.com";
     // specify should the output be ASCII or binary
     bool asciiArmor = false;
     // should additional integrity information be added   
     // set to true for compatibility with GnuPG 2.2.8+
     bool integrityCheck = false;
 
     pgp.EncryptFile(@"DataFiles\INPUT.txt",
                     keyStore,
                     publicKeyUserId,
                     @"DataFiles\OUTPUT.pgp",
                     asciiArmor,
                     integrityCheck);            
 }
}

VB.NET example

Imports System
Imports DidiSoft.Pgp
 
Public Class KeyStoreEncryptFile
  Public Shared Sub Demo()
   ' initialize the key store
   Dim keyStore As New KeyStore("DataFiles\key.store", "keystore passphrase")
   ' create an instance of the library
   Dim pgp As New PGPLib()
 
   Dim publicKeyUserId As String = "support@didisoft.com"
   ' specify should the output be ASCII or binary
   Dim asciiArmor As Boolean = False
   ' should additional integrity information be added   
   ' set to true for compatibility with GnuPG 2.2.8+
   Dim integrityCheck As Boolean = False
 
   pgp.EncryptFile("DataFiles\INPUT.txt", _
                     keyStore, _
	             publicKeyUserId, _
		     "DataFiles\OUTPUT.pgp", _
		     asciiArmor, _
		     integrityCheck)    
  End Sub
End Class

3. Encrypting a string message with a public key located in a file

Sometimes we may prefer to encrypt a string message directly in-memory instead of writing it to a file. The output, in this case, is directly in ASCII armored format so there is no need of this parameter:

C# example

using System;
using System.IO;
using DidiSoft.Pgp;
 
class EncryptString
{
 public void Demo() {
   // create an instance of the library
   PGPLib pgp = new PGPLib();
 
   String encryptedString =
	pgp.EncryptString("The quick brown fox jumps.", new FileInfo(@"DataFiles\public.asc"));
 }
}

VB.NET example

Imports System
Imports System.IO
Imports DidiSoft.Pgp
 
Class EncryptString
 Public Shared Function Demo() As String
  ' create an instance of the library
  Dim pgp As New PGPLib()
  Dim encryptedString As String = _
       pgp.EncryptString("The quick brown fox jumps.", New FileInfo("DataFiles\public.asc"))
  Return encryptedString
 End Function
End Class

4. OpenPGP Encrypting a string message with a public key located in a KeyStore

In this example, the public key of the recipient is stored in a KeyStore and we encrypt a string message directly.

C# example

using System;
using DidiSoft.Pgp;
 
class KeyStoreEncryptString
{
 public void Demo()
 {
   string recipientKeyUserId = "support@didisoft.com";
 
   // initialize the key store
   KeyStore ks = new KeyStore(@"DataFiles\key.store", "changeit");
 
   // if this key store contains a key with this recipient userId
   // then encrypt, otherwise notify that there is no such key
   if (ks.ContainsKey(recipientKeyUserId))
   {
    // create an instance of the library
    PGPLib pgp = new PGPLib();
 
    string plainText = "C# pgp encrypt made easy.";
 
    string encryptedString =
	    pgp.EncryptString(plainText, ks, recipientKeyUserId);
   }
   else
   {
    Console.WriteLine("No key with user Id:" + recipientKeyUserId + " was found in this key store.");
   }
 }
}

VB.NET example

Imports System
Imports DidiSoft.Pgp
 
Class KeyStoreEncryptString
 Public Sub Demo()
   Dim recipientKeyUserId As String = "support@didisoft.com"
 
   ' initialize the key store
   Dim ks As New KeyStore("DataFiles\key.store", "changeit")
 
   ' if this key store contains a key with this recipient userId
   ' then encrypt, otherwise notify that there is no such key
   If ks.ContainsKey(recipientKeyUserId) Then
        ' create an instance of the library
	Dim pgp As New PGPLib()
 
	Dim plainText As String = "VB.NET pgp encrypt made easy."
 
	Dim encryptedString As String = _
	    pgp.EncryptString(plainText, ks, recipientKeyUserId)
    Else
	Console.WriteLine("No key with user Id: " + recipientKeyUserId + " was found in this key store.")
    End If
 End Sub
End Class

5. Encrypting a stream

The library allows encrypting a stream. This can be useful for example if we do not want to write anything to the filesystem. The example below uses streams derived from files, but of course, they can be any subclass of System.IO.Stream.

C# example

using System.IO;
using DidiSoft.Pgp; 
 
class EncryptStreamDemo
{
 public void Demo()
 {
   PGPLib pgp = new PGPLib();
 
   using (Stream inputStream = File.OpenRead(@"DataFiles\INPUT.txt"))
   using (Stream publicKey = File.OpenRead(@"DataFiles\public.asc"))
   using (Stream encryptedStream = File.Create(@"DataFiles\OUTPUT.pgp"))
   {
     // specify should the output be ASCII or binary
     bool asciiArmor = true;
     pgp.EncryptStream(inputStream, publicKey, encryptedStream, asciiArmor);
   }
 }
}

VB.NET example

Imports System.IO
Imports DidiSoft.Pgp
 
Class EncryptStreamDemo
 Public Sub Demo()
     Dim pgp As New PGPLib()
 
     Using inputStream As Stream = File.OpenRead("DataFiles\INPUT.txt")
      Using publicKey As Stream = File.OpenRead("DataFiles\public.asc")
       Using encryptedStream As Stream = File.OpenWrite("DataFiles\OUTPUT.pgp")
 
        ' specify should the output be ASCII or binary
        Dim asciiArmor As Boolean = True
        pgp.EncryptStream(inputStream, publicKey, encryptedStream, asciiArmor)
       End Using
      End Using
    End Using
 End Sub
End Class

6. Encrypt a stream with recipient public key in a KeyStore object

This example is equivalent to the above one, except that the recipient public key used for encryption is stored in a KeyStore object.

C# example

using System.IO;
using DidiSoft.Pgp; 
 
class EncryptStreamDemo {
 public void Demo() {
   // init the KeyStore
   KeyStore keyStore = new KeyStore(@"c:\my.keystore", "password123");
   String recipientUserId = "support@didisoft.com";
 
   PGPLib pgp = new PGPLib();
 
   using (Stream inputStream = File.OpenRead(@"DataFiles\INPUT.txt"))
   using (Stream encryptedStream = File.Create(@"DataFiles\OUTPUT.pgp"))
   {
    // specify should the output be ASCII or binary
    bool asciiArmor = true;
    pgp.EncryptStream(inputStream, keyStore, recipientUserId, encryptedStream, asciiArmor);
   }
 }
}

VB.NET example

Imports System.IO
Imports DidiSoft.Pgp
 
Class EncryptStreamDemo
 Public Sub Demo()
     ' init the KeyStore
     Dim keyStore As New KeyStore("c:\my.keystore", "password123")
     Dim recipientUserId As String = "support@didisoft.com"
 
     Dim pgp As New PGPLib()
 
     Using inputStream As Stream = File.OpenRead("DataFiles\INPUT.txt")
      Using encryptedStream As Stream = File.OpenWrite("DataFiles\OUTPUT.pgp")
 
       ' specify should the output be ASCII or binary
       Dim asciiArmor As Boolean = True
 
       pgp.EncryptStream(inputStream, keyStore, recipientUserId, encryptedStream, asciiArmor)
     End Using
   End Using
 End Sub
End Class

7. Encrypting a file for multiple recipients

OpenPGP allows encrypting a file for multiple recipients if we have their public keys. The example below illustrates how to achieve that.

C# example

using System.IO;
using DidiSoft.Pgp; 
 
class EncryptForMultiRecipientsDemo {
  public void Demo() {
     PGPLib pgp = new PGPLib();
     // ASCII armor or binary
     bool asciiArmor = true;
     // append integrity protection check, set to true for compatibility with GnuPG 2.2.8+
     bool withIntegrityCheck = false;
 
     string[] recipientsPublicKeys =
                            {@"c:\recipient_1_key.asc",
                             @"c:\recipient_2_key.asc",
                             @"c:\recipient_3_key.asc"};
 
     pgp.EncryptFile(@"c:\INPUT.txt",
                     recipientsPublicKeys,
                     @"c:\OUTPUT.pgp",
                     asciiArmor,
                     withIntegrityCheck);
  }
}

VB.NET example

Imports System.IO
Imports DidiSoft.Pgp
 
Class EncryptForMultiRecipientsDemo
  Public Sub Demo()
    Dim pgp As New PGPLib()
    ' ASCII armor or binary
    Dim asciiArmor As Boolean = True
    ' append integrity protection check, set to true for compatibility with GnuPG 2.2.8+
    Dim withIntegrityCheck As Boolean = False
 
     Dim recipientsPublicKeys As String() = _
         New String() {"c:\recipient_1_key.asc", _
                       "c:\recipient_2_key.asc", _
                       "c:\recipient_3_key.asc"}
 
     pgp.EncryptFile("c:\INPUT.txt", _
			recipientsPublicKeys, _
			"c:\OUTPUT.pgp", _
			asciiArmor, _
			withIntegrityCheck)
	End Sub
End Class

8. Encrypting a file for multiple recipients with keys in a KeyStore

Here we are going to encrypt a file for multiple recipients having their public keys stored in a KeyStore.

C# example

using System;
using DidiSoft.Pgp;
 
public class EncryptFileMultiRcpt
{
 public static void Demo()
 {
	// initialize the key store
	KeyStore keyStore = new KeyStore(@"DataFiles\key.store", "changeit");
 
	// create an instance of the library
	PGPLib pgp = new PGPLib();
 
	// specify should the output be ASCII or binary
	bool asciiArmor = false;
	// should additional integrity information be added, set to true for compatibility with GnuPG 2.2.8+    
	bool withIntegrityCheck = false;
 
	string[] recipientsUserIds = {"support@didisoft.com",
					"john@acmcompany.com",
				        "golt@acmcompany.com"};
 
	pgp.EncryptFile(@"DataFiles\INPUT.txt",
			keyStore,
			recipientsUserIds,
			@"DataFiles\OUTPUT.pgp",
			asciiArmor,
			withIntegrityCheck);
 }
}

VB.NET example

Imports System
Imports DidiSoft.Pgp
 
Public Class EncryptFileMultiRcpt
 Public Shared Sub Demo()
	' initialize the key store
	Dim keyStore As New KeyStore("DataFiles\key.store", "changeit")
 
	' create an instance of the library
	Dim pgp As New PGPLib()
 
	' specify should the output be ASCII or binary
	Dim asciiArmor As Boolean = False
	' should additional integrity information be added, set to true for compatibility with GnuPG 2.2.8+    
	Dim withIntegrityCheck As Boolean = False
 
	Dim recipientsUserIds As String() = {"support@didisoft.com", _
						"john@acmcompany.com", _
						"golt@acmcompany.com"}
 
	pgp.EncryptFile("DataFiles\INPUT.txt", keyStore, _
			recipientsUserIds, _
			"DataFiles\OUTPUT.pgp", _
			asciiArmor, _
			withIntegrityCheck)
 End Sub
End Class

9. Encrypting multiple files in one OpenPGP archive

Encrypting multiple files into a single .pgp archive was first introduced by PGP(r) version 9 and later by other OpenPGP implementations.

Please have in mind that the recipient of the encrypted content should use PGP (r) 9+ or compatible software. This example will show how to encrypt multiple files in one OpenPGP archive with the library.

C# example

using System.IO;
using DidiSoft.Pgp;
 
class EncryptFilesDemo
{
 public void Demo()
 {
  // initialize the library
  PGPLib pgp = new PGPLib();
 
  // specify should the output be ASCII or binary
  bool asciiArmor = false;
  // should additional integrity information be added, set to true for compatibility with GnuPG 2.2.8+
  bool withIntegrityCheck = false;
 
  // files to be encrypted
  FileInfo[] inputFiles =
     new FileInfo[] {new FileInfo(@"c:\INPUT1.txt"), new FileInfo(@"c:\INPUT2.txt")};
 
  // one or more public keys to encrypt with
  FileInfo[] recipientPublicKeys = new FileInfo[] {new FileInfo(@"c:\public_key.asc")};
 
  // encryption output
  FileInfo encryptedOutputFile = new FileInfo(@"c:\OUTPUT.pgp");
 
  pgp.EncryptFiles(inputFiles,
		recipientPublicKeys,
		encryptedOutputFile,
		asciiArmor,
		withIntegrityCheck);
 }
}

VB.NET example

Imports System.IO
Imports DidiSoft.Pgp
 
Class EncryptFiles
 Public Shared Sub Demo()
  ' create an instance of the library
  Dim pgp As New PGPLib()
 
  ' specify should the output be ASCII or binary
  Dim asciiArmor As Boolean = True
  ' should additional integrity information be added, set to true for compatibility with GnuPG 2.2.8+
  Dim withIntegrityCheck As Boolean = True
 
  ' files to be encrypted
  Dim inputFiles As FileInfo() = New FileInfo() {New FileInfo("DataFiles\INPUT.txt"), _
                                                 New FileInfo("DataFiles\OUTPUT.txt")}
 
  ' one or more public keys to encrypt with
  Dim recipientPublicKeys As FileInfo() = _
    New FileInfo() {New FileInfo("DataFiles\public.key")}
 
  ' encryption output
  Dim encryptedOutputFile As New FileInfo("DataFiles\OUTPUT.pgp")
 
  pgp.EncryptFiles(inputFiles, _
		recipientPublicKeys, _
		encryptedOutputFile, _
		asciiArmor, _
		withIntegrityCheck)
 End Sub
End Class

10. Encrypting multiple files in one OpenPGP archive with keys in KeyStore

This example is equivalent to the previous one, but now the recipients’ public keys are stored in a KeyStore.

C# example

using System.IO;
using System;
using DidiSoft.Pgp;
 
public class EncryptFilesKS
{
 public static void Demo()
 {
	// initialize the key store
	KeyStore keyStore = new KeyStore(@"DataFiles\key.store", "changeit");
 
	// create an instance of the library
	PGPLib pgp = new PGPLib();
 
	// specify should the output be ASCII or binary
	bool asciiArmor = false;
	// should additional integrity information be added    
	bool withIntegrityCheck = false;
 
	string[] filesToEncrypt = {@"DataFiles\INPUT.txt",
				@"DataFiles\file2.jpg",
				@"DataFiles\file3.doc"};
 
	String publicKeyUserId = "support@didisoft.com";
	string[] recipientUserIds = { publicKeyUserId };
 
	pgp.EncryptFiles(filesToEncrypt,
			keyStore,
			recipientUserIds,
			@"DataFiles\OUTPUT.pgp",
			asciiArmor,
			withIntegrityCheck);
 }
}

VB.NET example

Imports System
Imports DidiSoft.Pgp
 
Public Class EncryptFiles
 Public Shared Sub Demo()
	' initialize the key store
	Dim keyStore As New KeyStore("DataFiles\key.store", "changeit")
 
	' create an instance of the library
	Dim pgp As New PGPLib()
 
	' specify should the output be ASCII or binary
	Dim asciiArmor As Boolean = False
	' should additional integrity information be added    
	Dim withIntegrityCheck As Boolean = False
 
	Dim filesToEncrypt As String() = {"DataFiles\INPUT.txt", _
					"DataFiles\public.key", _
					"DataFiles\private.key"}
 
	Dim publicKeyUserId As [String] = "support@didisoft.com"
	Dim recipientUserIds As String() = {publicKeyUserId}
 
	pgp.EncryptFiles(filesToEncrypt, keyStore, _
					recipientUserIds, _
					"DataFiles\OUTPUT.pgp", _
					asciiArmor, _
					withIntegrityCheck)
 End Sub
End Class

11. Encrypting a file only with a password

Encrypting a file with a password is also known as conventional encryption or password-based encryption (PBE). The recipient of the file will use the same password used for encryption to decrypt the file.

Under the hood, a symmetric key is derived from the provided password and depending on the default symmetric algorithm (by default AES-256), the data is encrypted.

C# example

using System.IO;
using DidiSoft.Pgp; 
 
class EncryptPasswordBasedDemo {
  public void Demo() {
    PGPLib pgp = new PGPLib();
    // specify should the output be ASCII or binary
    bool asciiArmor = true;
 
    pgp.EncryptFilePBE(new FileInfo(@"DataFiles\INPUT.txt"),
                       "password",
                       new FileInfo(@"DataFiles\OUTPUT.pgp"),
                       asciiArmor);
 }
}

VB.NET example

Imports System.IO
Imports DidiSoft.Pgp
 
Class EncryptPasswordBasedDemo
 Public Sub Demo()
   Dim pgp As New PGPLib()
   ' specify should the output be ASCII or binary
   Dim asciiArmor As Boolean = True
 
   pgp.EncryptFilePBE(New FileInfo("DataFiles\INPUT.txt"), _
                       "password", _
                       New FileInfo("DataFiles\OUTPUT.pgp"), _
                       asciiArmor)
  End Sub
End Class

A. Exception handling

All of the Encrypt methods throw two basic checked exceptions:

  • System.IO.IOException – in case of an I/O error
  • DidiSoft.Pgp.PGPException – if an OpenPGP encryption error occur

In a general scenario, we are going to catch only them.

If however, we would like to take recovery actions we would need more information for the error cause. For this purpose a few subclasses of DidiSoft.Pgp.PGPException can also be caught in order to identify with more details the error cause.

Below you will find an example code snippet with comments for each exception subclass.

C# example

using System;
using DidiSoft.Pgp;
using DidiSoft.Pgp.Exceptions;
 
public class ExceptionHandlingDemo
{
 public static void main(String[] args)
 {
  PGPLib pgp = new PGPLib();
  try
  {
     pgp.Encrypt...
  }
  catch (System.IO.IOException e)
  {
   // in case of an input file not found or other I/O related error
  }
  catch (DidiSoft.Pgp.Exceptions.WrongPublicKeyException e) 
  { 
   // The supplied public key is not a public key at all 
   // or does not contain an encryption key
   // For example we have supplied an arbitrary file for the public 
   // key file parameter, or in the case with a KeyStore parameter 
   // there is no key with the specified Key ID or User ID
  }
  catch (DidiSoft.Pgp.Exceptions.KeyIsExpiredException e) 
  { 
   // A supplied public key is expired 
   // (the system date is after the date specified inside the key 
   // as an expiration date)
   // We can still use such keys by setting the property UseExpiredKeys to true
  }
  catch (DidiSoft.Pgp.Exceptions.KeyIsRevokedException e) 
  { 
   // A supplied public key is revoked
   // (the key contains a revocation signature that marks it as not usable)
   // We can still use such keys by setting the property UseRevokedKeys to true
  }
  catch (DidiSoft.Pgp.PGPException e)  
  {
   // General OpenPGP error non among the above
  }			
 } 
}

VB.NET

Imports System
Imports DidiSoft.Pgp
Imports DidiSoft.Pgp.Exceptions
 
Public Class ExceptionDemo
 Public Shared Sub Demo()
  Dim pgp As New PGPLib()
 
  Try
   pgp.Encrypt...
  Catch e As System.IO.IOException
   ' in case of an input file not found or other I/O related error
  Catch e As DidiSoft.Pgp.Exceptions.WrongPublicKeyException
   ' The supplied public key is not a public key at all or does not 
   ' contain an encryption key
   ' For example we have supplied an arbitrary file for the 
   ' public key file parameter, or in the case with a KeyStore there is 
   ' no key with the specified Key ID or User ID
  Catch e As DidiSoft.Pgp.Exceptions.KeyIsExpiredException
   ' A supplied public key is expired 
   ' (the system date is after the date specified inside the key 
   ' as an expiration date)
   ' We can still use such keys by setting the property UseExpiredKeys to true
  Catch e As DidiSoft.Pgp.Exceptions.KeyIsRevokedException
   ' A supplied public key is revoked
   ' (the key contains a revocation signature that marks it as not usable)
   ' We can still use such keys by setting the property UseRevokedKeys to true
  Catch e As DidiSoft.Pgp.PGPException
   ' General OpenPGP error non among the above
  End Try
 End Sub
End Class

Asynchronous methods

Asynchronous methods are available only for .NET 4.5+, .NET Core, .NET Standard 2+, Xamarin, UWP, WinRT.
In order to use similar Async variants of the methods shown above, instantiate PGPLibAsync instead of PGPLib.

1-A. Encrypting a file asynchronously

Encrypting a file asynchronously, requires the public key of the recipient. The output encrypted file can be in binary format or in text/ascii armored format.

C# example

using System.Threading;
using DidiSoft.Pgp;
 
    class EncryptFileAsync
    {
        public async void Demo()
        {
            // create an instance of the library
            PGPLibAsync pgp = new PGPLibAsync();
 
            // is the output ASCII or binary            
            bool asciiArmor = true;
            // should the output be integrity protected
            bool integrityProtect = true;
            // cancelation token if we want to cancel the process at any time
            CancellationToken token = default(CancellationToken);
            await pgp.EncryptFileAsync(@"DataFiles\INPUT.txt",
                            @"DataFiles\public.key",
                            @"DataFiles\OUTPUT.pgp",
                            asciiArmor,
                            integrityProtect,
                            token);
        }
    }

2-A. Async encrypting a file with keys in a KeyStore

We can also encrypt a file asynchronously with a public key located in a KeyStore.
The same additional parameters: determining the ascii or binary output, the integrity protection and a cancelation token apply here too.

C# example

using System.Threading;
using DidiSoft.Pgp;
 
    class EncryptFileAsync
    {
        public async void Demo()
        {
            // initialize the key store
            KeyStore keyStore = new KeyStore(@"DataFiles\key.store", "changeit");
 
            // create an instance of the library
            PGPLibAsync pgp = new PGPLibAsync();
 
            // specify should the output be ASCII or binary
            bool asciiArmor = false;
            // should additional integrity information be added    
            bool withIntegrityCheck = false;
 
            // a key with this User Id should be available in the provided KeyStore
            // otherwise a DidiSoft.Pgp.Exceptions.WrongPublicKeyException will be thrown
            String publicKeyUserId = "nosuchemail@didisoft.com";
 
            await pgp.EncryptFileAsync(@"DataFiles\INPUT.txt",
                            keyStore,
                            publicKeyUserId,
                            @"DataFiles\OUTPUT.pgp",
                            asciiArmor,
                            withIntegrityCheck);
        }
    }

3-A Encrypting a string in OpenPGP format with a public key located in a file

Encrypting a String message results in ASCII armored (textual) encrypted output:

C# example

using DidiSoft.Pgp;
 
public class EncryptStringAsync
{
   public async void Demo()
   {
     // create an instance of the library
     PGPLibAsync pgp = new PGPLibAsync();
 
     String encryptedString =
          await pgp.EncryptStringAsync("The quick brown fox jumps.", @"DataFiles\public.asc" );
   }
}

4-A Async Encrypting a string message with a public key located in a KeyStore

The result OpenPGP encrypted string is integrity protected by default. The cancelation token is an optional parameter and can be skipped.

C# example

using System.Threading;
 
using DidiSoft.Pgp;
 
public class EncryptStringAsyncKS
{
 public async void Demo()
 {
  string recipientKeyUserId = "support@didisoft.com";
 
  // initialize the key store
  KeyStore ks = new KeyStore(@"DataFiles\key.store", "changeit");
 
  // create an instance of the library
  PGPLibAsync pgp = new PGPLibAsync();
 
  string plainText = "Hello World";
  // the cancelation token is optional but we provide it for clarity
  CancellationToken token = default(CancellationToken);
  string encryptedString = await pgp.EncryptStringAsync(plainText, ks, recipientKeyUserId, token);
 }
}

5. OpenPGP Encrypting a Stream Asynchronously

When encrypting a Stream asynchronously, the same parameters that modify the output format apply as well: ascii armor, integrity protection and of course cancelation token.

It is important to note the confusing file name label parameter as well. Imagine a ZIP file that contains inside a file with a name completely different from the enclosing ZIP file name. Here the file name label is for the same purpose – to associate a file name with the encrypted data, thus giving a hint to decryption programs if they want to extract he file to this name.

C# example

using DidiSoft.Pgp;
using System.IO;
public class EncryptStreamAsyncDemo
{
 public async void Demo()
 {
	// initialize the library
	PGPLibAsync pgp = new PGPLibAsync();
 
	// encryption key
	using (Stream publicKeyStream = File.OpenRead(@"DataFiles\public.asc"))
	// data stream to be encrypted
	using (Stream dataStream = File.OpenRead(@"DataFiles\INPUT.txt"))
	// the encrypted output can be any kind of stream
	using (Stream encryptedOutput = File.Create(@"DataFiles\output.pgp"))
	{
		// specify is output ASCII (true) or binary (false)
		bool asciiArmor = true;
		// file name label associated with the encrypted data 
		string internalFileNameLabel = "Data.txt";
 
		await pgp.EncryptStreamAsync(dataStream,
					    internalFileNameLabel,
					    publicKeyStream,
					    encryptedOutput,
					    asciiArmor);
	}
 }
}

6.-A OpenPGP Encrypting a stream Asynchronously with KeyStore

This sample is equivalent to the above one, except that this time the public key is located in a KeyStore object and referenced via the email part of the key User Id.

In the code below, the encrypted data will be associated with the DefaultFileName label property of the PGPLibAsync instance, but of course an overloaded version also exists where the internal file name label can be specified explicitly.

C# example

using System.Threading;
using DidiSoft.Pgp;
using System.IO;
public class EncryptStreamAsync
{
 public async void Demo()
 {
   // initialize the library
   PGPLibAsync pgp = new PGPLibAsync();
 
   // initialize the key store
   KeyStore ks = new KeyStore(@"DataFiles\key.store", "changeit");
   string recipientKeyUserId = "support@didisoft.com";
 
   // data stream to be encrypted
   using (Stream dataStream = File.OpenRead(@"DataFiles\INPUT.txt"))
   // the encrypted output can be any kind of stream
   using (Stream encryptedOutput = File.Create(@"DataFiles\oput.pgp"))
   {
 
    // specify is output ASCII or binary
    bool asciiArmor = true;
 
    // should the output be integrity protected
    bool integrityProtect = true;
    // optional parametere cancelation token
    // if we want to cancel the process at any time
    CancellationToken token = default(CancellationToken);
 
    await pgp.EncryptStreamAsync(dataStream,
                          ks,
                          recipientKeyUserId,
                          encryptedOutput,
                          asciiArmor,
                          integrityProtect,
                          token);
   }
  }
}

7.-A OpenPGP Encrypt a file for multiple recipients asynchronously

The example code below illustrates how to OpenPGP encrypt a file for multiple recipients, providing the public key of each recipient.
For simplicity the cancelation token available as optional last parameter, is omitted. Input data available as Stream or as String can also be encrypted for multiple recipients, with the appropriate overloaded versions of the PGPLibAsync.EncryptStreamAsync and PGPLibAsync.EncryptStringAsync methods.

C# example

using System.IO;
using DidiSoft.Pgp; 
 
    public class EncryptFileMultiRcptAsync
    {
        public async void Demo()
        {
            PGPLibAsync pgp = new PGPLibAsync();
            // ASCII armor or binary
            bool asciiArmor = true;
 
            string[] recipientsPublicKeys =
                                   {@"c:\recipient_1_key.asc",
                                    @"c:\recipient_2_key.asc",
                                    @"c:\recipient_3_key.asc"};
 
            await pgp.EncryptFileAsync(@"c:\INPUT.txt",
                            recipientsPublicKeys,
                            @"c:\OUTPUT.pgp",
                            asciiArmor);
        }

8.-A Encrypting a file asynchronusly for multiple recipients with keys in a KeyStore

We can also OpenPGP encrypt a file with an Async method with mutiple keys from a KeyStore.

C# example

using System;
using DidiSoft.Pgp;
 
public class EncryptFileMultiRcptAsync
{
 public async void Demo()
 {
	// initialize the key store
	KeyStore keyStore = new KeyStore(@"DataFiles\key.store", "changeit");
 
	// create an instance of the library
	PGPLib pgp = new PGPLib();
 
	// specify should the output be ASCII or binary
	bool asciiArmor = false;
 
	string[] recipientsUserIds = {"support@didisoft.com",
					"john@acmcompany.com",
				        "golt@acmcompany.com"};
 
        await pgp.EncryptFileAsync(@"DataFiles\INPUT.txt",
                            keyStore,
                            recipientsUserIds,
                            @"DataFiles\OUTPUT.pgp",
                            asciiArmor);
 
 }
}

9.-A Encrypting multiple files in one OpenPGP archive Async

Encrypting multiple files into a single OpenPGP archive is an advanced operation and is not very common among business organizations that exchange encrypted files.
Before using any flavor of the code below, you have to be sure that the recipient will be able to handle such multi file package.

Cancelation token can also be specified as a last parameter.

C# example

using System.IO;
using DidiSoft.Pgp;
 
class EncryptFilesDemo
{
        public async void Demo()
        {
            // initialize the library
            PGPLibAsync pgp = new PGPLibAsync();
 
            // specify should the output be ASCII or binary
            bool asciiArmor = false;
 
            // files to be encrypted
            string[] inputFiles =
               new string[] {@"DataFiles\INPUT.txt",
                             @"DataFiles\OUTPUT.txt"};
 
            // one or more public keys to encrypt with
            string[] recipientPublicKeys =
               new string[] { @"DataFiles\public.key" };
 
            // encryption output
            string encryptedOutputFile = @"DataFiles\OUTPUT.pgp";
 
            await pgp.EncryptFilesAsync(inputFiles,
                                recipientPublicKeys,
                                encryptedOutputFile,
                                asciiArmor);
        }
}

VB.NET example

10.-A Encrypting multiple files in one OpenPGP archive with keys in KeyStore Async

In addition to encrypting multiple files in a single OpenPGP archive, the method EncryptFileAsync also allows easily multiple recipients to be specified by their User ID’s or Key ID’s.

C# example

using System.IO;
using System;
using DidiSoft.Pgp;
 
public class EncryptFilesAsyncDemo
{
 public static void Demo()
 {
            // initialize the key store
            KeyStore keyStore = new KeyStore(@"DataFiles\key.store", "changeit");
 
            // create an instance of the library
            PGPLibAsync pgp = new PGPLibAsync();
 
            // specify should the output be ASCII or binary
            bool asciiArmor = false;
 
            string[] filesToEncrypt = {@"DataFiles\INPUT.txt",
                                        @"DataFiles\public.key",
                                        @"DataFiles\private.key"};
 
            string publicKeyUserId = "support@didisoft.com";
            string[] recipientUserIds = { publicKeyUserId };
 
            pgp.EncryptFilesAsync(filesToEncrypt,
                            keyStore,
                            recipientUserIds,
                            @"DataFiles\OUTPUT.pgp",
                            asciiArmor);
 }
}

Summary

In this chapter, we have introduced OpenPGP encryption using DidiSoft OpenPGP Library for .NET.

For other OpenPGP related operations like decrypting and one pass encrypt and sign, please check the table of contents.

Content type
A special content type flag can be set in order for the recipient to correctly handle encrypted text data.

PGP 2.x compatibility
If you have to encrypt data for older PGP 2.x systems, check how to enable PGP 2.x compatibility.

List methods used

Method  Description
PGPLib.EncryptFile Encrypts a file
PGPLib.EncryptString Encrypts a string message
PGPLib.EncryptStream Encrypts a stream into another stream
PGPLib.EncryptFiles Encrypts multiple files and/or folders into a single OpenPGP archive
PGPLib.EncryptFilePBE Encrypts a file with a password (and a key(s) optionally)
PGPLibAsync.EncryptFileAsync Async Encrypts a file
PGPLibAsync.EncryptStringAsync Async Encrypts a string message
PGPLibAsync.EncryptStreamAsync Async Encrypts a stream into another stream
PGPLib.EncryptFilesAsync Async Encrypts multiple files and/or folders into a single OpenPGP archive

 Back to TOC