Saturday, July 26, 2014

Java: PGP Sign and Encrypt Strings

Source Code
Speaking at Hope X in 2014, Edward Snowden suggested developers should champion design solutions that implement information encryption-tech as a first class citizen. Without getting too nuanced about what that means, here are a few technical thoughts on a design solution I ran across while implementing a solution recently.

Forgetting that PGP tools are poorly adopted for even their most prevalent uses cases like simple E-mail communications: they're even less prevalent in the simple messaging systems that users often find themselves interacting with in web-based messaging applications.

I would argue that even if a software architect would like to have these solutions implemented, there exists a real lack of developer APIs to streamline implementing these processes.

One of the first things that strikes me when I Google DuckDuckGo for a library or source-code examples for putting PGP into my software applications, is that most examples uses these tools to PGP encrypt files on disk!

When is the last time, in 2014, you as a developer implemented your solution to read and write your users messages to a FLAT-FILE SYSTEM ON DISK?!

The answer is: YOU DON'T. Your solutions pass messages through in-memory strings, that are saved in a database or e-mailed or streamed to your users browsers!

In this simple example, I'm using a few methods to read-in a set of PGP-keys I've generated (Yes -they're stored on disk*) and 1. Generate a PGP Signature of my string, using my private-key, and 2. Encrypt my message with my public-key. Without reading or writing the message from DISK!

I'm using Java's Bouncy Castle library. The "Documentation" is pretty dense. So I ended up looking for an example that fits this use case.

First, in Java, it's important to add BC as a "Security Provider".

Note: In a cute-irony the Bouncy Castle libraries WILL FAIL to work properly unless you update your Java JRE with the Unlimited Strength Jurisdiction Policy files. Implementing source code that helps the North Koreans or the Iranians encrypt their E-Mails may result in 20-years in a "Pound me in the Ass Federal Penitentiary"? That's right. You've just cross the thin-red line, bro, no turning back now. (Que Scene from Office Space where they install the virus...)

Next we need to to actually load our PGP-Key files. Which is easier said than done. The API's in bouncing castle and most other libraries behave in a key-chain manner, where we can load a file that contains multiple keys.

And the Private-Key:
Something to note here, we're opening the "Secret Key" key: which ISN'T actually our Private Key in code, this is because our priv. key is still hashed with the password I set when I created it.

So we need to unlock it. This is the first place I got an exception before I updated my JRE (See above)

Ok, cool. We've got our keys! Now here's the trick, we're going to take our input string and perform the signature and encryption with it them:

First with our private key, we want to sign our message:


That was dense. And to be perfectly frank, the fact that I can't wrap this operation into a method: Is one of the major issues why developers aren't making encryption a first-class citizen in their implementations.

Moving on.

Next, we want to encrypt our string.

Again, pretty dense. A few things to note in the above routine: Some of the methods are now marked as deprecated in Bouncy Castle, which arguably is more important when dealing with cryptography than any other area of writing code. For brevity however, I'm not going to let perfect be the enemy of good in sourcing this out.

* Storing of the actual key-files is something of a conundrum to me. The simple solution of storing a public-key in a database makes the most sense, as you could encrypt messages before they are transmitted from your web-application. However, how to safely "store" a private-key in relationship to your executing code is a matter for a real security expert in key-storage.

No comments:

Post a Comment