pgp detached signature in C# and VB.NET

OpenPGP detached signatures are stored in a separate file from the data, which differs from the standard OpenPGP signature format containing the data and the signature combined in one file.

The detached signature is produced by a PGP private key. For the verification of detached signatures, we need the corresponding public key.

A common file naming convention for files containing detached signatures is to have the same name as the original file with an additional .sig filename extension at the end.

Below we are going to demonstrate how to perform OpenPGP detached signing with DidiSoft OpenPGP Library for .NET

Detached signatures can be in binary format or in the OpenPGP ASCII armored form, so all methods used in the example below have a ascii armor boolean parameter (when true the output will be ASCII armored otherwise binary).

Detached signing a file

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

Detached signing a Stream

3. with a private key supplied as Stream | Async
4. with a private key located in a KeyStore | Async

Detached signing a String

5. Detached signing a string message | Async

Verifying detached signed data

6. verify detached signed file | Async
7. verify detached signed String message | Async
8. verify detached signed Stream data | Async

Appendix
A. Exception Handling

1. Detached signing a file

In this example, we will produce an OpenPGP detached signature for a file and store the signature also in a file.

C# example

using System;
using DidiSoft.Pgp;
 
public class DetachedSignDemo
{
  public static void Demo()
  {
   // create an instance of the library
   PGPLib pgp = new PGPLib();
 
  // should the output be binary (false) or ASCII armored (true)
  bool asciiArmor = true;
 
  pgp.DetachedSignFile(@"c:\INPUT.txt",
			 @"c:\my_private_key.asc",
			 "my key password",
			 @"c:\INPUT.txt.sig",
			 asciiArmor);
  }
}

VB.NET example

Imports System
Imports DidiSoft.Pgp
 
Public Class DetachedSignDemo
 Public Shared Sub Demo()
  ' create an instance of the library
  Dim pgp As New PGPLib()
 
  ' should the output be binary (false) or ASCII armored (true)
  Dim asciiArmor As Boolean = True
 
  pgp.DetachedSignFile("c:\INPUT.txt", _
			"c:\my_private_key.asc", _
			"my key password", _
			"c:\INPUT.txt.sig", _
			asciiArmor)
 End Sub
End Class

1-A. Async Detached signing a file

We can create an OpenPGP detached signature for a file with the help of the DetachedSignFileAsync method from the PGPLibAsync class:

using System;
using System.Threading;
using System.Threading.Tasks;
 
using DidiSoft.Pgp;
 
class DetachedSignFileAsyncDemo
{
 public async Task Demo()
 {
  // create an instance of the library
  PGPLibAsync pgp = new PGPLibAsync();
 
  // should the output be binary (false) or ASCII armored (true)
  bool asciiArmor = true;
 
  // optional
  CancellationToken token = default(CancellationToken);
 
  await pgp.DetachedSignFileAsync(@"c:\INPUT.txt",
		   @"c:\my_private_key.asc",
		   "my key password",
		   @"c:\INPUT.txt.sig",
		   asciiArmor,
		   token);
 }
}

2. Detached signing a file with a private key located in a KeyStore

This example is equivalent to the above one, except that the private key used for signing is located in a KeyStore. The private signing key can be referred with its User Id or Key Hex Id.

C# example

using System;
using DidiSoft.Pgp;
 
public class DetachedSignDemo
{
 public void Demo()
 {
   // initialize the key store
   KeyStore ks = KeyStore.OpenFile(@"c:\mykey.store", "key store password");
 
   // create an instance of the library  
   PGPLib pgp = new PGPLib();
 
   // should the output be ASCII (true) or binary (false) 
   bool asciiArmor = true;
 
   // The private key can be specified through it's Key Hex Id too
   string privateKeyUserId = "support@didisoft.com";
   string privateKeyPassword = "key password";
 
   pgp.DetachedSignFile(@"C:\Test\INPUT.txt", 
			ks,
			privateKeyUserId, 
			privateKeyPassword,
			@"C:\Test\INPUT.txt.sig", 
			asciiArmor);				
 }
}

VB.NET example

Imports System
Imports DidiSoft.Pgp
 
Public Class DetachedSignDemo
 Public Shared Sub Demo()
   ' initialize the key store
   Dim ks As KeyStore = KeyStore.OpenFile("DataFiles\key.store", "key store password")
 
   ' create an instance of the library 
   Dim pgp As New PGPLib()
 
   ' should the output be ASCII (true) or binary (false) 
   Dim asciiArmor As Boolean = True
 
   ' The private key can be specified through it's Key Hex Id too
   Dim privateKeyUserId As String = "support@didisoft.com"
   Dim privateKeyPassword As String = "private key password"
 
   pgp.DetachedSignFile("C:\Test\INPUT.txt", _
                        ks, _
                        privateKeyUserId, _
                        privateKeyPassword, _
                        "C:\Test\INPUT.txt.sig", _
                        asciiArmor)
 End Sub
End Class

2-A. Async creation of an OpenPGP detached signature from a File with a key in a KeyStore

We can also asynchronously create a PGP detached signature from a file with a private key located in a KeySore file.
For simplicity we use a dummy CancellationToken but it can be skipped altogether as it is an optional parameter.

using System;
using System.Threading;
using System.Threading.Tasks;
 
using DidiSoft.Pgp;
 
class DetachedSignFileAsyncKSDemo
{
 public async Task Demo()
 {
  // initialize the key store
  KeyStore ks = KeyStore.OpenFile(@"c:\mykey.store", "key store password");
 
  // create an instance of the library  
  PGPLibAsync pgp = new PGPLibAsync();
 
  // should the output be ASCII (true) or binary (false) 
  bool asciiArmor = true;
 
  // The private key can be specified through it's Key Hex Id too
  string privateKeyUserId = "support@didisoft.com";
  string privateKeyPassword = "key password";
 
  // optional parameter
  CancellationToken token = default(CancellationToken);
 
  await pgp.DetachedSignFileAsync(@"C:\Test\INPUT.txt",
		 ks,
		 privateKeyUserId,
		 privateKeyPassword,
		 @"C:\Test\INPUT.txt.sig",
		 asciiArmor, token);
 }
}

3. Producing a PGP detached signature from a Stream

In this example, we will produce a detached signature for data provided as Stream. The detached signature is also stored in a Stream.

C# example

using System;
using DidiSoft.Pgp;
 
public class DetachedSignStreamDemo
{
  public static void Demo()
  {
      // initialize the library
      PGPLib pgp = new PGPLib();
 
      // should the output be binary or ASCII armored 
      bool asciiArmor = true;
 
      using (Stream dataFileStream = File.OpenRead(@"C:\INPUT.txt"))
      using (Stream privateKeyStream = File.OpenRead(@"C:\private_key.asc"))
      using (Stream outputSigned = File.Create(@"C:\INPUT.txt.sig")
      {
        pgp.DetachedSignStream(dataFileStream, 
                              privateKeyStream, 
                              "private key password",
                              outputSigned, 
                              asciiArmor);				
      }
  }
}

VB.NET example

Imports System
Imports DidiSoft.Pgp
 
Public Class DetachedSignStreamDemo
 Public Shared Sub Demo()
    ' initialize the library 
    Dim pgp As New PGPLib()
 
    ' should the output be binary or ASCII armored 
    Dim asciiArmor As Boolean = True
 
    Dim dataFileStream As Stream = File.OpenRead("C:\INPUT.txt")
    Dim privateKeyStream As Stream = File.OpenRead("C:\private_key.asc")
 
    Using outputSigned As Stream = File.Create("C:\INPUT.txt.sig")
     pgp.DetachedSignStream(dataFileStream, _
                            privateKeyStream, _
                            "private key password", _
                            outputSigned, _
                            asciiArmor)
    End Using
 End Sub
End Class

3-A. Async PGP detached signature from a Stream

Detached OpenPGP signature from character data provided as a Stream can be created with PGPLibAsync.DetachedSignStream:

using System;
using System.IO;
using System.Threading;
using System.Threading.Tasks;
 
using DidiSoft.Pgp;
 
class DetachedSignStreamAsyncDemo
{
 public async Task Demo()
 {
  // initialize the library
  PGPLibAsync pgp = new PGPLibAsync();
 
  // should the output be binary or ASCII armored 
  bool asciiArmor = true;
 
  // optional parameter
  CancellationToken token = default(CancellationToken);
 
  using (Stream dataFileStream = File.OpenRead(@"C:\INPUT.txt"))
  using (Stream privateKeyStream = File.OpenRead(@"C:\private_key.asc"))
  using (Stream outputSigned = File.Create(@"C:\INPUT.txt.sig"))
  {
	await pgp.DetachedSignStreamAsync(dataFileStream,
						  privateKeyStream,
						  "private key password",
						  outputSigned,
						  asciiArmor,
						  token);
  }
 }
}

4. Produce a detached signature from a Stream with а key located in a KeyStore

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

C# example

using System;
using DidiSoft.Pgp;
 
public class DetachedSignStreamDemo
{
  public static void Demo()
  {
      // create an instance of the library
      PGPLib pgp = new PGPLib();
 
      // should output be binary (false) or ASCII armored (true)
      bool asciiArmor = true;
 
      // initialize the KeyStore
      KeyStore ks = new KeyStore(@"c:\mykey.store", "key store password");
 
      // The private key can be specified through it's Key Hex Id too
      string privateKeyUserId = "support@didisoft.com";
 
      using (Stream dataFileStream = File.OpenRead(@"C:\INPUT.txt"))
      using (Stream outputSigned = File.Create(@"C:\INPUT.txt.sig"))
      {
        pgp.DetachedSignStream(dataFileStream, 
                              ks, 
                              privateKeyUserId,
                              "private key password",
                              outputSigned, 
                              asciiArmor);				
      }
  }
}

VB.NET example

Imports System
Imports DidiSoft.Pgp
 
Public Class DetachedSignStreamDemo
 Public Shared Sub Demo()
    ' initialize the library 
    Dim pgp As New PGPLib()
 
    ' should the output be binary or ASCII armored 
    Dim asciiArmor As Boolean = True
 
    ' initialize the key store
    Dim ks As New KeyStore("DataFiles\key.store", "key store password")
 
    ' The private key can be specified through it's Key Hex Id too
    Dim privateKeyUserId As String = "support@didisoft.com"
 
    Dim dataFileStream As Stream = File.OpenRead("C:\INPUT.txt")
 
    Using outputSigned As Stream = File.Create("C:\INPUT.txt.sig")
      pgp.DetachedSignStream(dataFileStream, _
                             ks, _
                             privateKeyUserId, _
                             "private key password", _
                             outputSigned, _
                             asciiArmor)
    End Using
 End Sub
End Class

4-A. Async detached signatures from a data Stream with а key located in a KeyStore

We can also create detached OpenPGP signatures with a key obtained from a KeyStore as you can see in the sample code below:

using System;
using System.IO;
using System.Threading;
using System.Threading.Tasks;
 
using DidiSoft.Pgp;
 
class DetachedSignStreamAsyncDemo2
{
 public async Task Demo()
 {
  // create an instance of the library
  PGPLibAsync pgp = new PGPLibAsync();
 
  // should output be binary (false) or ASCII armored (true)
  bool asciiArmor = true;
 
  // initialize the KeyStore
  KeyStore ks = new KeyStore(@"c:\mykey.store", "key store password");
 
  // The private key can be specified through it's Key Hex Id too
  string privateKeyUserId = "office@didisoft.com";
 
  // optional parameter
  CancellationToken token = default(CancellationToken);
 
  using (Stream dataFileStream = File.OpenRead(@"C:\INPUT.txt"))
  using (Stream outputSigned = File.Create(@"C:\INPUT.txt.sig"))
  {
	await pgp.DetachedSignStreamAsync(dataFileStream,
					  ks,
					  privateKeyUserId,
					  "private key password",
					  outputSigned,
					  asciiArmor);
  }
 }
}

5. Detached signing a string message

Below is shown how to detached sign a string message and get the signature as a string too.
All DetachedSignString provided by the PGPLib class produce detached signatures in ASCII armored format as a String can contain only character data.
C# example

using System;
using System.IO;
using DidiSoft.Pgp;
 
class DetachedSignStringDemo
{
  public void Demo()
  {
   String plainString = "Hello World";
 
   // initialize the library
   PGPLib pgp = new PGPLib();
 
   Stream privateKeyStream = File.OpenRead(@"c:\my_private_key.asc");
 
   String signatureString = pgp.DetachedSignString(plainString,
						privateKeyStream,
						"my key password");
   Console.WriteLine(signatureString);
  }
}

VB.NET example

Imports System
Imports System.IO
Imports DidiSoft.Pgp
 
Class DetachedVerifyString
 Public Sub Demo()
  Dim plainString As String = "Hello World"
 
  ' initialize the library
  Dim pgp As New PGPLib()
 
  Dim privateKeyStream As Stream = File.OpenRead("c:\my_private_key.asc")
 
  Dim signatureString As String = _
       pgp.DetachedSignString(plainString, _
                              privateKeyStream, _
                              "my key password")
 
  Console.WriteLine(signatureString)
 End Sub
End Class

5-A. Async Detached signing a string message

OpenPGP detached signature over data contained in a variable of type String can be created with the DetachedSignStringAsync method from the PGPLibAsync class:

using System;
using System.Threading;
using System.Threading.Tasks;
 
using DidiSoft.Pgp;
 
class DetachedSignStringAsync
{
 public async Task Demo()
 {
  String plainString = "Hello World";
 
  // initialize the library
  PGPLibAsync pgp = new PGPLibAsync();
 
  // this can also be the key serialzied as ASCII string
  string privateKey = @"c:\my_private_key.asc";
 
  // optional parameter
  CancellationToken token = default(CancellationToken);
 
  String signatureString = 
	await pgp.DetachedSignStringAsync(plainString,
					privateKey,
					"my key password",
				        token);
 
  Console.WriteLine(signatureString);
 }
}

6. Verify a detached signed file

We need the original data file in order to verify against it the detached signature file.

Also the public OpenPGP key corresponding to the private key that created the signature is needed. When using a KeyStore we can verify the signature against all public keys contained in the KeyStore, this way omitting the need to provide different public key when receiving data from multiple recipients.

This is illustrated in the example code below:

using System;
using DidiSoft.Pgp;
using DidiSoft.Pgp.Exceptions;
 
class DetachedVerifyFile
{
 public static void Demo()
 {
  // create an instance of the library
  PGPLib pgp = new PGPLib();
 
  SignatureCheckResult signatureCheck = pgp.DetachedVerifyFile(@"DataFiles\INPUT.txt",
								@"DataFiles\INPUT.txt.sig",
								@"DataFiles\public.key");
 
  // the same verification process but against all public keys from a KeyStore
  KeyStore keystore = new KeyStore(@"DataFile\my.keystore", "my kjeystore pass");
  signatureCheck = pgp.DetachedVerifyFile(@"DataFiles\INPUT.txt",
						@"DataFiles\INPUT.txt.sig",
					        keystore);
 
 
  if (signatureCheck == SignatureCheckResult.SignatureVerified)
  {
	Console.WriteLine("Signature OK");
  }
  else if (signatureCheck == SignatureCheckResult.SignatureBroken)
  {
	Console.WriteLine("Signature of the message is either broken or forged");
  }
  else if (signatureCheck == SignatureCheckResult.PublicKeyNotMatching)
  {
	Console.WriteLine("The provided public key doesn't match the signature");
  }
  else if (signatureCheck == SignatureCheckResult.NoSignatureFound)
  {
	Console.WriteLine("This message is not digitally signed");
  }
 }
}

6-A. Async Verifing a detached signed file

Asynchronous verification of a detached signature is provided by PGPLibAsync.DetachedVerifyFileAsync:

using System.Threading;
using DidiSoft.Pgp;
...
PGPLibAsync pgp = new PGPLibAsync();
// optional parameter
CancellationToken token = default(CancellationToken);
SignatureCheckResult check = await pgp.DetachedVerifyFileAsync(@"c:\INPUT.txt", @"c:\INPUT.txt.sig", @"c:\public.asc");

7. Verify a detached signed String

Below is shown how to verify a detached String signature. For the verification, we also need the String message for which it was created.

C# example

using System;
using System.IO;
using DidiSoft.Pgp;
 
class DetachedVerifyStringDemo
{
  public void Demo()
  {
    String plainString = "Hello World";
 
    // initialize the library 
    PGPLib pgp = new PGPLib();
 
    Stream privateKeyStream = File.OpenRead(@"c:\private_key.asc");
 
    String signedString = pgp.DetachedSignString(plainString,
						privateKeyStream,
						"key password");
    Console.WriteLine(signedString);
 
    Stream publicKeyStream = File.OpenRead(@"c:\public_key.asc");
 
    bool correct = pgp.DetachedVerifyString(plainString, 
                                            signedString, 
                                            publicKeyStream);
    if (correct)
    {
	Console.WriteLine("Signature is correct");
    }
    else
    {
	Console.WriteLine("Signature is wrong.");
     }
  }
}

VB.NET example

Imports System
Imports System.IO
Imports DidiSoft.Pgp
 
Class DetachedVerifyString
 Public Sub Demo()
   Dim plainString As String = "Hello World"
 
  ' initialize the library 
  Dim pgp As New PGPLib()
 
  Dim privateKeyStream As Stream = File.OpenRead("c:\private_key.asc")
 
  Dim signedString As String = pgp.DetachedSignString(plainString, _
                                                      privateKeyStream, _
                                                      "key password")
  Console.WriteLine(signedString)
 
  Dim publicKeyStream As Stream = File.OpenRead("c:\private_key.asc")
 
  Dim correct As Boolean = pgp.DetachedVerifyString(plainString, _
                                                    signedString, _
                                                    publicKeyStream)
  If correct Then
	Console.WriteLine("Signature is correct")
  Else
	Console.WriteLine("Signature is wrong.")
  End If
 End Sub
End Class

6-A. Async verification of a detached signed String

Asynchronous verification of a detached signature is provided by PGPLibAsync.DetachedVerifyStringAsync:

using System.Threading;
using DidiSoft.Pgp;
...
PGPLibAsync pgp = new PGPLibAsync();
// optional parameter
CancellationToken token = default(CancellationToken);
// this can also be the public key serialized in ASCII armored format
string publicKey = @"c:\public.asc";
SignatureCheckResult check = await pgp.DetachedVerifyStringAsync(messageString, signatureString, publicKey);

7. Verify a detached signed Stream data

This example demonstrates how to verify detached Stream data. The data, the detached signature and the public key that will be used for the verification are obtained as Streams from files, but of course, they can be any kind of Stream subclass.

C# example

using System;
using System.IO;
using DidiSoft.Pgp;
 
class DetachedVerifyDemo
{
 public static void Demo()
 {
  // create an instance of the library
  PGPLib pgp = new PGPLib();
 
  bool signatureIsValid = false;
  using (Stream dataStream = File.OpenRead(@"c:\INPUT.txt"))
  {
    using (Stream signatureStream = File.OpenRead(@"c:\INPUT.txt.sig"))
    {
 	using (Stream publicKeyStream = File.OpenRead(@"c:\public_key.asc"))
	{
 	 signatureIsValid = pgp.DetachedVerifyStream(dataStream,
						     signatureStream,
						     publicKeyStream);
	}
    }
  }
 
  if (signatureIsValid)
  {
	Console.WriteLine("Signature is valid.");
  }
  else
  {
	Console.WriteLine("Signature is invalid!");
  }
 }
}

VB.NET example

Imports System
Imports System.IO
Imports DidiSoft.Pgp
 
Class DetachedVerifyDemo
 Public Shared Sub Demo()
  ' create an instance of the library
  Dim pgp As New PGPLib()
 
  Dim signatureIsValid As Boolean = False
  Using dataStream As Stream = File.OpenRead("DataFiles\INPUT.txt")
    Using signatureStream As Stream = File.OpenRead("DataFiles\INPUT.txt.sig")
	Using publicKeyStream As Stream = File.OpenRead("DataFiles\public.key")
		signatureIsValid = _
			pgp.DetachedVerifyStream(dataStream, _
						signatureStream, _
						publicKeyStream)
	End Using
    End Using
  End Using
 
  If signatureIsValid Then
	Console.WriteLine("Signature is valid.")
  Else
	Console.WriteLine("Signature is invalid!")
  End If
 End Sub
End Class

7-A. Async verifying a detached signed Stream

When the input data and the signature are available as Streams we can used the set of DetachedVerifyStreamAsync methods in order to verify the consistency of the signature and the data.

using System.Threading;
using DidiSoft.Pgp;
...
PGPLibAsync pgp = new PGPLibAsync();
// optional parameter
CancellationToken token = default(CancellationToken);
using (Stream dataFileStream = File.OpenRead(@"C:\INPUT.txt"))
using (Stream publicKeyStream = File.OpenRead(@"C:\public_key.asc"))
using (Stream signedStream = File.OpenRead(@"C:\INPUT.txt.sig"))
{
 SignatureCheckResult check  = 
  await pgp.DetachedVerifyStreamAsync(dataFileStream,
                                      signedStream,
                                      publicKeyStream,
                                      token);
}

Appendix A. Exception Handling

All DetachedSign and DetachedVerify methods throw System.IO.IOException in case of an I/O error and DidiSoft.Pgp.PGPException in case of an OpenPGP related error.
We can investigate further an OpenPGP exception cause by trying to check is the exception of a given subclass defined in the DidiSoft.Pgp.Exceptions namespace.

Below is an example that illustrates what are the expected exception subclasses from the DetachedSign and DetachedVerify methods.

C# example

PGPLib pgp = new PGPLib();
try
{
  pgp.DetachedSign...
}
catch (System.IO.IOException e)
{
  // in case of an input file not found or other I/O related error
}
catch (DidiSoft.Pgp.PGPException e)
{
  if (e is DidiSoft.Pgp.Exceptions.WrongPrivateKeyException)
  {
   // The supplied private key source is not a private key at all 
   // or does not contain a signing key
   // For example we have supplied an arbitrary file for the private 
   // key parameter, or in the case with a KeyStore parameter 
   // there is no private key with the specified Key ID or User ID
  }
  else if (e is DidiSoft.Pgp.Exceptions.WrongPasswordException)
  {
   // The supplied private key password is misspelled
  }
  else
  {
   // General OpenPGP error non among the above
  }
}
 
try
{
  pgp.DetachedVerify...
}
catch (System.IO.IOException e)
{
  // in case of an input file not found or other I/O related error
}
catch (DidiSoft.Pgp.PGPException e)
{
  if (e is DidiSoft.Pgp.Exceptions.NonPGPDataException)
  {
   // The supplied detached signed data is corrupted or is not an OpenPGP data at all
  }
  else
  {
   // General OpenPGP error non among the above
  }
}

VB.NET example

Dim pgp As New PGPLib()
Try
  pgp.DetachedSign...
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.PGPException
  If TypeOf e Is DidiSoft.Pgp.Exceptions.WrongPrivateKeyException Then
   ' The supplied private key source is not a private key at all 
   ' or does not contain a signing key
   ' For example we have supplied an arbitrary file for the private 
   ' key parameter, or in the case with a KeyStore parameter 
   ' there is no private key with the specified Key ID or User ID	
  ElseIf TypeOf e Is DidiSoft.Pgp.Exceptions.WrongPasswordException Then
   ' The supplied private key password is misspelled	
  Else
   ' General OpenPGP error non among the above	
  End If
End Try
 
Try
  pgp.DetachedVerify...
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.PGPException
  If TypeOf e Is DidiSoft.Pgp.Exceptions.NonPGPDataException Then
   ' The supplied detached signed data is corrupted or is not an OpenPGP data at all
  Else
   ' General OpenPGP error non among the above	
  End If
End Try

Back to Top

Summary

In this chapter we have discussed OpenPGP detached signatures and how to produce them using DidiSoft OpenPGP Library for .NET.

List of methods used:

PGPLib.DetachedSignFile Creates an OpenPGP detached signature for a file
PGPLib.DetachedSignStream Creates an OpenPGP detached signature for the contents of a Stream
PGPLib.DetachedSignFile Creates an OpenPGP detached signature for a String message
PGPLib.DetachedVerifyFile Verifies an OpenPGP detached signature available as file
PGPLib.DetachedVerifyString Verifies an OpenPGP detached signature available as String
PGPLib.DetachedVerifyStream Verifies an OpenPGP detached signature available as Stream
PGPLibAsync.DetachedSignFileAsync Asynchronosuly Creates an OpenPGP detached signature for a file
PGPLibAsync.DetachedSignStreamAsync Asynchronosuly Creates an OpenPGP detached signature for the contents of a Stream
PGPLibAsync.DetachedSignFileAsync Asynchronosuly Creates an OpenPGP detached signature for a String message
PGPLibAsync.DetachedVerifyFileAsync Asynchronosuly Verifies an OpenPGP detached signature available as file
PGPLibAsync.DetachedVerifyStringAsync Asynchronosuly Verifies an OpenPGP detached signature available as String
PGPLibAsync.DetachedVerifyStreamAsync Asynchronosuly Verifies an OpenPGP detached signature available as Stream