Verify signed data in .NET (OLD)

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

A. Exception handling

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

Back to Top

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

Back to Top

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

Back to Top

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

Back to Top

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

Back to Top

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

Back to Top

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

Back to Top

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