Encryption, Decryption, AES, PGP, Oh My!

Professor Stick talks AES
Professor Stick talks AES

Jeff Moser has an enlightened, and entertaining explanation of the Advanced Encryption Standard on his web site, Moserware. As Jeff describes the explanation, its a play in four acts. I had to exit the stage when the stick figure professor got into the heavy math, but it was a great lesson, none the less.

You can head on over to Jeff’s site to check it all out. In fact, I suggest reading it, even if you’re not really that into encryption standards and technology. Its a great primer.

Jeff also posted some sample files about how to use AES on GitHub, which got me thinking about an encryption / decryption article I wrote recently. For the PGP Decryption with C Sharp post I wrote, I created a handy sample application and a small library, both of which are available on this site today.

I haven’t really done anything with GitHub, despite its simplicity and audience. So today, after my AES education with Professor Stick, I decided to setup a GitHub account and share my PGP Encryption with C Sharp examples there too.

Enjoy.

PGP Decryption with C#

PGP Decryption Pictogram
PGP Decryption Pictogram

One of my recent projects was to create a Windows desktop application that would allow a user to select a PGP encrypted file, select and output destination and click a button to have that file decrypted. There were a few other things the application needed to do, like verify the information in the file, but that was the easy part.

The real challenge was to load up the public and private key rings and decrypt the source file. I have a pretty good understanding of the concepts behind PGP (symmetric key) encryption, so it seemed like a fairly straight forward project. However, as most software developers know, perception and reality rarely align.

I started out looking for a .Net library that would encapsulate all of the PGP processes for me. Turns out, there are several, but most of them are commercial products and there just wasn’t any money in the project budget for that. So I keep looking and eventually, I came across the Legion of the Bouncy Castle, which provides an extensive encryption library. It was originally for Java, but has been ported to C#. Perfect!

This thing's got class(es)!
This thing's got class(es)!

I downloaded the non-IDEA library, referenced it in my project and voila! Except, not so much. There was a ton classes, but nothing referencing OpenPGP directly, and that’s what I needed.

I read through a ton of information on the Bouncy Castle site, and it looks like there should be a .OpenPgp class included. So I spent a bit more time searching through Google to find an example or two of others that were already using Bouncy Castle in C#.

If you’ve been trying to do the same thing, you already know that there aren’t very many good samples out there. I did find an excellent piece on how to encrypt files using PGP and the Bouncy Castle library by the .Net Geek. If you’re looking to encrypt files, this is a great place to start. I’ve incorporated this code into my crypto library that is below. I’ve also included links to a number of sites and articles that I read while working on this project. I hope you will find this information useful as well.

With a good example in hand, I started working out how to make the decryption side of things work. Again, its fairly straightforward, you just need to know what sort of stream you’re looking for at each stage of the process. Similar to the .Net Geek, I like to figure out how I’m going to consume the provider before I write it. That helps to make sure that the classes are easy to use and work like I’m expecting. I’ve provided a sample application and a crypto wrapper library at the bottom of this entry. Feel free to jump ahead.

All I wanted to do from my application was call the decryption routine and pass in the path to the encrypted file.

?View Code CSHARP
1
2
3
4
public bool DecryptFile(string encryptedFilePath)
{
    return decryptInputFile(encryptedFilePath);
}

The next step is setup the crypto wrapper and actually decode the file. I decided that I would simply remove the .gpg from the end of my encrypted file and use that as the destination file. In my case, I also had to process this intermediate file to ensure that all of the information was valid.

?View Code CSHARP
1
2
3
4
5
6
string outputFile = extractOutputFileName(encryptedFileName);
 
private string extractOutputFileName(string encryptedFileName)
{
      return encryptedFileName.Substring(0, encryptedFileName.LastIndexOf('.'));
}

Now I need to get everything ready to call the decrypt and verify method in the cryptography library. In my particular implementation, I wanted to be able to say that the decryption failed, but it wasn’t important to the end user exactly why, so it’s just true or false.

?View Code CSHARP
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
private bool decryptInputFile(string encryptedFileName)
{
     bool returnCode;
     string outputFile = extractOutputFileName(encryptedFileName);
     try
     {
          SPL.Crypto.PgpEncryptionKeys keys = new PgpEncryptionKeys(publicKeyRingPath, secretKeyRingPath, passPhrase);
          PgpDecrypt decryptor = new PgpDecrypt(keys);
          Stream encryptedStream = new StreamReader(encryptedFileName).BaseStream;
          decryptor.DecryptAndVerify(encryptedStream, outputFile);
          returnCode = true;
     }
     catch (Exception)
     {
          // If there was an error, we're going to eat it and just let the user know we failed.
          returnCode = false;
     }
     return returnCode;
}

Once the decryption object had been setup, it was just a matter of invoking DecryptAndVerify. This method works through all of the different streams and transforms each into the next, finally resulting in the clear text document that we write out to the file system. None of the streams used in the decryption process are saved any where, they’re just kept in memory while they’re being used.

?View Code CSHARP
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
private void decryptAndVerify(Stream inputStream, string outputFilePath)
{
     PgpPublicKeyEncryptedData publicKeyED = extractPublicKeyEncryptedData(inputStream);
     PgpObject message = getClearCompressedMessage(publicKeyED);
 
     if (message is PgpCompressedData)
     {
         message = processCompressedMessage(message);
         PgpLiteralData literalData = (PgpLiteralData)message;
         using (Stream outputFile = File.Create(outputFilePath))
         {
            using (Stream literalDataStream = literalData.GetInputStream())
            {
                Streams.PipeAll(literalDataStream, outputFile);
            }
         }
     }
 
     return;
}

I’ll leave the details of how it all works to the samples and the cryptography library below. All of the source is included for your reference.

9/23/2009 UPDATE

I added the sample files from this post to GitHub. Feel free to access the sample files there too.

More Information:

  • Bouncy Castle – http://www.bouncycastle.org/
  • Karmin’s Blog – http://karym6.blogspot.com/2009/06/pgp-decryption-with-c.html
  • .Net Geek – http://blogs.microsoft.co.il/blogs/kim/archive/2009/01/23/pgp-zip-encrypted-files-with-c.aspx
  • Jesse’s Blog – http://elian.co.uk/post/2009/07/29/Bouncy-Castle-CSharp.aspx
  • Aaron Johnson – http://cephas.net/blog/2004/09/03/pgp-decryption-using-c/

Sample Files:

Working with Twitterizer

I’ve been working on a custom FTP application for the past few days. The application is designed to read a list of remote resource files and go and download each file.

This application will be automated once its setup in production. No one will have to interact with it on a daily basis – it will just go and do the job it was designed for. Part of that job is to log its actions, so that the IT staff can review what’s happened and track down any issues that may come up.

Twitter
Twitter

If you’re on the web at all these days, you’ve no doubt, heard of Twitter. Its simple format makes it a great tool for sharing status information. It seemed to me that having the application tweet its status would be an easy, fun way to use Twitter and provide some semi-useful information.

Twitter exposes an extensive application programming interface, API, for third party developers to use. I briefly considered rolling my own wrappers for the Twitter API. However, that really wasn’t in the best interest my small project’s time line.

Instead, I decided to do a little searching for a pre-written, community supported, API wrapper for .Net. That’s when I found Twitterizer. The project is hosted on Google Code, so getting the files was a snap.

I downloaded the most recent, stable release (1.0.1.99 as I write this), and added it into my C# project. I had already setup a new account with Twitter for the application to use when broadcasting it’s status updates, so I had everything ready to go.

As I wrote the FTP application, I included a number of events that could be logged. Each log item, like the start of a download, had a “level” associated with it. The “level” allowed me to make the application really talkative, or fairly mute, depending on the configuration files.

Knowing that I wouldn’t want everything out on the application’s Twitter feed, I setup a special “log to twitter” minimum level for logging. If the log message was below the threshold, then the application would tweet it too. I also included a setting in the configuration file to disable the Twitter logging completely.

Working with Twitterizer couldn’t have been any easier. Their API wrapper has everything you need to easily send a status update.

?View Code CSHARP
1
2
3
4
5
6
7
8
9
10
11
12
13
14
private void statusUpdate(string message, Utilities.LogLevel logLevel)
{
       string tweet = string.Concat(message, " #fr");
       if (tweet.Length > 140)
       {
           tweet = tweet.Substring(0, 140);
       }
 
       if (this.twitterEnabled && logLevel < = this.twitterLogLevel)
       {
           Twitter twitter = new Twitter(this.twitterUserName, this.twitterPassword);
           twitter.Status.Update(tweet);
       }
}

That’s all it took. Two lines of actual code to implement the status update using Twitterizer.

Is an application that tweets all that useful? Probably not. It was, however, fun to make it all work.