Azure Functions

In this tutorial, we are going to describe how to use and deploy DidiSoft OpenPGP Library for .NET with Microsoft Azure Function Apps.

1. .NET Function App
2. PowerShell Core Function App
3. Processing Large Files

.NET (C#) Function App

The steps below describe the deployment of the library in a Function App that reads and writes data to Azure Blob storage. A video and steps by step instructions follow below:

Transcript and Step by Step instructions

Using OpenPGP Library for .NET on Azure in a few words is no different from any other type of .NET project. We just reference the library assemblies and invoke the PGP cryptography methods.

But when using Azure there are some DevOps steps that we have to perform beforehand in order to prepare the deployment environment.

Creating a Function App

The default settings are enough for our demo application. The “

The runtime stack will be .NET Core. We will reuse an existing storage account and an existing resource group. Application Insights are optional but useful for tracing errors and exceptions.

Once the Function App has been created we can open Visual Studio and create a Function App from a template.

For this example, we will be using a Blob trigger, but developing another type of Function Apps will be very much similar.

Our code will take as input data uploaded to a Blob storage container (container1) and will put this data OpenPGP encrypted into another Blob storage container (container2), by appending a “.pgp” file extension to the original input file name.

namespace MyPgpFunctions
{
    public static class FunctionPgp
    {
        [FunctionName("FunctionPgp")]
        public static void Run([BlobTrigger("container1/{name}", Connection = "AzureWebJobsStorage")]Stream myBlob,
                               [Blob("container2/{name}.pgp", FileAccess.Write, Connection = "AzureWebJobsStorage")]Stream outBlob,
                               string name, 
	                       ILogger log)
        {
        }
    }
}

Referencing DidiSoft.Pgp.dll via NuGet

In order to use the library, we have to add references to it. We can do that by getting it from NuGet. For a demo project we will be using the trial version from nuget.org (In production of course we’ll be using the private NuGet repository instead):

Install-Package DidiSoft.Pgp.Trial

Then we can modify the Blob trigger code, by invoking the encryption method like:

using DidiSoft.Pgp;
namespace MyPgpFunctions
{
    public static class FunctionPgp
    {
        [FunctionName("FunctionPgp")]
        public static void Run([BlobTrigger("storage1/{name}", Connection = "AzureWebJobsStorage")]Stream myBlob,
                               [Blob("storage2/{name}.pgp", FileAccess.Write, Connection = "AzureWebJobsStorage")]Stream outBlob,
                               string name, 
	                       ILogger log)
        {
            PGPLib pgp = new PGPLib();
            bool asciiArmor = true;
 
	    inlinePublicKey = "... hardcoded public key ...";
            pgp.EncryptStream(myBlob, name, inlinePublicKey, outBlob, asciiArmor);
        }
    }
}

The key can be hardcoded for a test project, but in a real-world scenario, it shall be obtained from a Key Vault.

Now we are ready to deploy the solution to Azure into the Function App that we have created at the beginning (mypgpfunc).

Once the application has been deployed we can upload a file in Azure Blob storage container “container1

The uploaded file it will automatically become encrypted by the Blob trigger in container2 as shown below:


PowerShell Core Function App

For an Azure Function App with PowerShell Core as Runtime stack, we have to load the DidiSoft.Pgp assemblies manually via PowerShell.

For PowerShell Core 7.0 we have to use the files from the folder \OpenPGP Library for .NET 1.9.3\Bin\NetStandard2.0.

In the example code which represents an Http PowerShell Trigger function, we have copied the files in the /bin subfolder. This trigger encrypts with a password in PGP format the “Message” request parameter and outputs the encrypted result.

using namespace System.Net
 
# Input bindings are passed in via param block.
param($Request, $TriggerMetadata)
 
Import-Module "C:\home\site\wwwroot\bin\DidiSoft.Pgp.dll"
Import-Module "C:\home\site\wwwroot\bin\DidiSoft.BouncyCastle.dll"
 
$msg = $Request.Query.Message
if (-not $msg) {
    $msg = $Request.Body.Message
}
 
$pgp = New-Object DidiSoft.Pgp.PGPLib
$encryptedString = $pgp.EncryptStringWithPassword($msg, "password")
 
$body = $encryptedString
# Associate values to output bindings by calling 'Push-OutputBinding'.
Push-OutputBinding -Name Response -Value ([HttpResponseContext]@{
    StatusCode = [HttpStatusCode]::OK
    Body = $body
})

Processing Large Files

With large input files, we may reach the maximum execution time of a Function App. In that case, it is a good idea to start a Batch Service Job from the Function App.

Summary

This tutorial is an introduction to how to get started with OpenPGP Library for .NET and Azure. The library can be used inside all Azure services implemented with .NET or PowerShell.