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
2. with a public key located in a KeyStore
Encrypting a String
3. with a public key located in a file
4. with a public key located in a KeyStore
Encrypting a Stream
5. with a key provided as Stream
6. with a key located in a KeyStore
Multiple recipients
7. Encrypting for multiple recipients
8. Encrypting for multiple recipients with a KeyStore
Multiple files
9. Encrypting multiple files into a single archive
10. Encrypting multiple files with keys in a KeyStore
OpenPGP password encryption
11. Encrypting with a password
Appendix
Asynchronous methods
Asynchronous methods are available only for .NET 4.5+, .NET Core, Xamarin, UWP, WinRT.
In order to use similar Async variants of the methods shown below, instantiate PGPLibAsync instead of PGPLib, like this:
PGPLibAsync pgp = new PGPLibAsync(); await pgp.EncryptFileAsync(dataFile, publicKeyFile, encryptedFile, asciiArmour); |
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. 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.
Please have in mind that it is less secure than the standard OpenPGP encryption performed with a public key.
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 |
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) |