This tutorial refers to version 1.7.11.x and prior of DidiSoft OpenPGP Library for .NET. For newer versions of the library please refer to the new version of the tutorial.
When we receive a signed or clear text signed OpenPGP data, we can both verify that it came from the sender we expect it and extract the original message at the same time. For the verification we need the public key of the sender. Of course we can ignore completely the digital signature and extract the data with a simple decryption.
The examples below demonstrate how to verify signed data with DidiSoft OpenPGP Library for .NET
Verify a signed or clear text signed file
1. with a sender’s public key located in a file
2. with a sender’s public key located in a KeyStore
Verify a signed or clear text signed String message
4. with a sender’s public key located in a file
3. with a sender’s public key located in a KeyStore
Verify a signed or clear text signed Stream
5. with a sender’s public key as Stream
6. with a sender’s public key located in a KeyStore
Appendix
1. Verifying a signed or clear text signed file using sender’s public key located also in a file
There is also an overloaded version of the VerifyFile method that allows just to verify the digital signature without actually extracting the data.
C# example
using System; using DidiSoft.Pgp; public class VerifyDemo { public void Demo() { // create an instance of the library PGPLib pgp = new PGPLib(); // check the signature and extract the data bool validSignature = pgp.VerifyFile(@"C:\Test\INPUT.pgp", @"C:\Test\public_key.asc", @"C:\Test\OUTPUT.txt"); Console.WriteLine("Valid Signature: " + validSignature); } } |
VB.NET example
Imports System Imports DidiSoft.Pgp Public Class VerifyDemo Public Sub Demo() ' create an instance of the library Dim pgp As New PGPLib() ' check the signature and extract the data Dim validSignature As Boolean = _ pgp.VerifyFile("C:\Test\INPUT.pgp", _ "C:\Test\public_key.asc", _ "C:\Test\OUTPUT.txt") Console.WriteLine("Valid Signature: " + validSignature) End Sub End Class |
2. Verify a signed or clear text signed file using sender’s public key located in a KeyStore
This example is equivalent to the above one, except that the public key of the sender is located in a KeyStore object. The digital signature will be verified among all the public keys in the specified KeyStore.
C# example
using System; using DidiSoft.Pgp; class KeyStoreVerifyFile { public static void Demo() { // create an instance of the library PGPLib pgp = new PGPLib(); // initialize the KeyStore // If the keystore file does not exists, it is created. KeyStore ks = new KeyStore(@"DataFiles\key.store", "changeit"); // verify OpenPGP signed or clear text signed file string outputFileLocation = @"c:\OUTPUT.txt"; bool validSignature = pgp.VerifyFile(@"c:\signed.pgp", ks, outputFileLocation); // Print the results Console.WriteLine("Extracted data in " + outputFileLocation); if (validSignature) { Console.WriteLine("Signature is valid"); } else { Console.WriteLine("Signature is invalid"); } } } |
VB.NET example
Imports System Imports DidiSoft.Pgp Class KeyStoreVerifyFile Public Shared Sub Demo() ' create an instance of the library Dim pgp As New PGPLib() ' initialize the KeyStore ' If the keystore file does not exists, it is created. Dim ks As New KeyStore("DataFiles\key.store", "changeit") ' verify OpenPGP signed or clear text signed file Dim outputFileLocation As String = "DataFiles\OUTPUT.txt" Dim validSignature As Boolean = _ pgp.VerifyFile("DataFiles\OUTPUT.pgp", _ ks, _ outputFileLocation) ' Print the results Console.WriteLine("Extracted data in " + outputFileLocation) If validSignature Then Console.WriteLine("Signature is valid") Else Console.WriteLine("Signature is invalid") End If End Sub End Class |
3. Verify a String message using sender public key located in a file
C# example
using System; using System.IO; using DidiSoft.Pgp; class VerifyString { public static void Demo() { // obtain an OpenPGP signed message String signedString = SignString.Demo(); // Extract the message and check the validity of the signature String plainText; PGPLib pgp = new PGPLib(); bool validSignature = pgp.VerifyString(signedString, new FileInfo(@"c\public_key.asc"), out plainText); // Print the results Console.WriteLine("Extracted plain text message is " + plainText); if (validSignature) { Console.WriteLine("Signature is valid"); } else { Console.WriteLine("Signature is invalid"); } } } |
VB.NET example
Imports System Imports System.IO Imports DidiSoft.Pgp Class VerifyString Public Shared Sub Demo() ' obtain an OpenPGP signed message Dim signedString As String = SignString.Demo() ' Extract the message and check the validity of the signature Dim plainText As String Dim pgp As New PGPLib() Dim validSignature As Boolean = _ pgp.VerifyString(signedString, _ New FileInfo("c:\public_key.asc"), _ plainText) ' Print the results Console.WriteLine("Extracted plain text message is " + plainText) If validSignature Then Console.WriteLine("Signature is valid") Else Console.WriteLine("Signature is invalid") End If End Sub End Class |
4. Verify a string message using sender’s public key located in a KeyStore
If we keep our OpenPGP keys in a KeyStore we should use the overloaded VerifyString method that accepts a KeyStore object:
C# example
using System; using DidiSoft.Pgp; class KeyStoreVerifyString { public static void Demo() { // obtain an OpenPGP signed message String signedString = KeyStoreSignString.Demo(); // Extract the message and check the validity of the signature String plainText; PGPLib pgp = new PGPLib(); KeyStore ks = new KeyStore(@"DataFiles\key.store", "changeit"); bool validSignature = pgp.VerifyString(signedString, ks, out plainText); // Print the results Console.WriteLine("Extracted plain text message is " + plainText); if (validSignature) { Console.WriteLine("Signature is valid"); } else { Console.WriteLine("Signature is invalid"); } } } |
VB.NET example
Imports System Imports DidiSoft.Pgp Class KeyStoreVerifyString Public Shared Sub Demo() ' obtain an OpenPGP signed message Dim signedString As String = KeyStoreSignString.Demo() ' Extract the message and check the validity of the signature Dim plainText As String Dim pgp As New PGPLib() Dim ks As New KeyStore("DataFiles\key.store", "changeit") Dim validSignature As Boolean = pgp.VerifyString(signedString, ks, plainText) ' Print the results Console.WriteLine("Extracted plain text message is " + plainText) If validSignature Then Console.WriteLine("Signature is valid") Else Console.WriteLine("Signature is invalid") End If End Sub End Class |
5. Verify a signed or clear text signed Stream with a sender’s public key as Stream
This example shows how to verify data that is in a Stream for reading. The extracted data is stored also in a Stream.
using System; using System.IO; using DidiSoft.Pgp; public class VerifyStream { public void Demo() { // create an instance of the library PGPLib pgp = new PGPLib(); // The data and the public key can be any kind of stream Stream dataStream = File.OpenRead(@"c:\signed.pgp"); Stream publicKeyStream = File.OpenRead(@"c:\public_key.asc"); Stream outputStream = new MemoryStream(); // verify signed or clear text signed stream bool validSignature = pgp.VerifyStream(dataStream, publicKeyStream, outputStream); Console.WriteLine("Signature is valid: " + validSignature); // We must reinitialize the output in order to read from it outputStream = new MemoryStream((outputStream as MemoryStream).ToArray()); } } |
VB.NET example
Imports System Imports System.IO Imports DidiSoft.Pgp Public Class VerifyStream Public Sub Demo() ' create an instance of the library Dim pgp As New PGPLib() ' The data and the public key can be any kind of stream Dim dataStream As Stream = File.OpenRead("c:\signed.pgp") Dim publicKeyStream As Stream = File.OpenRead("c:\public_key.asc") Dim outputStream As Stream = New MemoryStream() ' verify signed or clear text signed stream Dim validSignature As Boolean = _ pgp.VerifyStream(dataStream, _ publicKeyStream, _ outputStream) Console.WriteLine("Signature is valid: " + validSignature) ' We must reinitialize the output in order to read from it outputStream = New MemoryStream(TryCast(outputStream, MemoryStream).ToArray()) End Sub End Class |
6. Verify a Stream when the public key of the sender is in a KeyStore
This example is equivalent to the above one, except that the sender’s public key is located in a KeyStore.
C# example
using System; using System.IO; using DidiSoft.Pgp; class KeyStoreVerifyStream { public static void Demo() { // create an instance of the library PGPLib pgp = new PGPLib(); // initialize the KeyStore that contains the sender's public key KeyStore ks = new KeyStore(@"c:\my_key.store", "changeit"); // The data and the output can be any kind of stream Stream dataStream = File.OpenRead(@"c:\signed.pgp"); Stream outputStream = new MemoryStream(); // verify string outputFileLocation = @"c:\OUTPUT.txt"; bool validSignature = pgp.VerifyStream(dataStream, ks, outputStream); // We must reinitialize the output in order to read from it outputStream = new MemoryStream((outputStream as MemoryStream).ToArray()); if (validSignature) { Console.WriteLine("Signature is valid"); } else { Console.WriteLine("Signature is invalid"); } } } |
VB.NET example
Imports System Imports System.IO Imports DidiSoft.Pgp Class KeyStoreVerifyStream Public Shared Sub Demo() ' create an instance of the library Dim pgp As New PGPLib() ' initialize the KeyStore that contains the sender's public key Dim ks As New KeyStore("c:\my_key.store", "changeit") ' The data and the output can be any kind of stream Dim dataStream As Stream = File.OpenRead("c:\signed.pgp") Dim outputStream As Stream = New MemoryStream() ' verify Dim outputFileLocation As String = "c:\OUTPUT.txt" Dim validSignature As Boolean = pgp.VerifyStream(dataStream, ks, outputStream) ' We must reinitialize the output in order to read from it outputStream = New MemoryStream(TryCast(outputStream, MemoryStream).ToArray()) If validSignature Then Console.WriteLine("Signature is valid") Else Console.WriteLine("Signature is invalid") End If End Sub End Class |
Appendix A. Exception Handling
The exception handling code when verifying signed data shall follow the general exception strategy.
This example illustrates the expected exceptions from the methods with a Verify name prefix.
C# example
using System; using DidiSoft.Pgp; using DidiSoft.Pgp.Exceptions; public class VerifyDemo { public void Demo() { // create an instance of the library PGPLib pgp = new PGPLib(); // verify bool validSignature = false; try { validSignature = pgp.Verify ... } catch (PGPException e) { if (e is NonPGPDataException) { // The input is not an OpenPGP archive or is corrupted } else if (e is WrongPublicKeyException) { // The supplied public key is not an OpenPGP public key // or is corrupted } else if (e is FileIsEncryptedException) { // The input file is OpenPGP encrypted. // You will have to use one of the Decrypt // or DecryptAndVerify methods } else { // general OpenPGP error Console.WriteLine(e.Message); } } } } |
VB.NET example
Imports System Imports DidiSoft.Pgp Imports DidiSoft.Pgp.Exceptions Public Class VerifyDemo Public Sub Demo() ' create an instance of the library Dim pgp As New PGPLib() ' verify Dim validSignature As Boolean = False Try validSignature = pgp.VerifyFile("DataFiles\OUTPUTs.pgp", _ "DataFiles\public.key", _ "DataFiles\OUTPUT.txt") Catch e As PGPException If TypeOf e Is NonPGPDataException Then ' The input file is not an OpenPGP archive or is corrupted ElseIf TypeOf e Is WrongPublicKeyException Then ' The supplied public key is not an OpenPGP public key ' or is corrupted ElseIf TypeOf e Is FileIsEncryptedException Then ' The input is OpenPGP encrypted. ' You will have to use one of the Decrypt or ' DecryptAndVerify methods instead Else ' general OpenPGP error Console.WriteLine(e.Message) End If End Try End Sub End Class |
Summary
In this chapter we have shown how to verify an OpenPGP digital signatures and extract the signed content. The examples above apply only to signed and clear text signed data.
Additional methods exist for verification of detached signatures and one pass signed and encrypted data.
You may also be interested in analyzing OpenPGP archive and checking the signing Key ID’s before performing signature verification.
Methods used in this chapter:
PGPLib.VerifyFile | Verifies an OpenPGP signed or clear text signed file |
PGPLib.VerifyString | Verifies an OpenPGP signed or clear text signed String message |
PGPLib.VerifyStream | Verifies an OpenPGP signed or clear text signed Stream |