AlgoDiscoDev Software Development

GnuPG (gpg) Encryption Using JSON Profiles

Information Privacy and Security == Freedom of Expression, Freedom of Communication and ultimately, Freedom of Thought.

A bit philosophical, but it's assumed that you're sort of in agreement, otherwise you might be wondering, what is the point of this project.

< pada

"Cloud, Cloud, Cloud."

Project Summary

I wrote a GnuPG encryption command generator. Is that good?

This program is effectively a source code generator. It uses a template, along with user provided parameters, to generate what in this instance, is the code to be issued as a gpg command.

The funny thing is, until I had to start writing this report to try to describe what I'd done, I had no clue that I'd written was what could be called a source code generator. All I knew was that it solved my problem. My knowledge of source code generators was almost zero.

Actually, when I realised that that's what I'd done, I initially felt a bit disgusted.

I mean I could already see sceptical eyes rolling as they read a report that seemed to be proposing a one-click-cure-all. They'd be wondering, "What's the catch?"

A bit of Research to Classify this Project

My only understanding of source code generation was of no-code, low-code, no-idea-how-this-code-works-but-don't-worry-about-it code, typical of the most instant-results-offering website builders. I'd heared that they could be built easily and quickly, but attempts to migrate or make changes by hand usually broke them.

Then I was reminded that web application frameworks like Laravel, Ruby on Rails and CodeIgniter are all template-based, to speed up application development. Even my favouite source code editor makes development easier and quicker by offering me boilerplate template code structures. A bit more research revealed that there was once even a project, called [# argbash #] - a command-line argument parser for shell scripts.

Rule of thumb: The less opinionated the code generator, the more bloated it has to be. Every possible intended meaning of that 'single click' has to be branched out in advance.

Ok then, if the product of this project is a source code generator, at least its' scope is highly specific.

  • It only generates a single line of code - a gpg command.
  • It is (so far) highly opinionated, for example, insisting on the best-practice, obligatory addition of either .gpg or .asc extensions to the filenames of encrypted messages.

Anyway, on to the actual problem I wanted to solve...

Background

This report does not describe a solution looking for a problem.

Being able to control our information and the information with which we're entrusted is no longer just a nice-to-have for professionals in all fields who need to remain trusted as reasonably competent.

GnuPG is a tool for encrypting stuff. Usually documents and images that we need to communicate over any channel, but particularly email. It has many capabilties that implement security concepts and best practices.

Email communication is still analogous to sending a postcard.

The internet is not a trusted network.

The Problem

I once heared it said that if you're not managing the encryption keys for your data, it's not your data.

But organising, managing and using encryption keys properly can get complicated.

Use Case

  1. You use the Linux command line.
  2. You're aware that although encrypted using TLS between you and your email provider, while your email content and attachments are stored for some time (or perhaps indefinitely) on each of the mail servers on their subsequent journey across the world, ...
  3. You sometimes use the GnuPG (gpg) utility to public key encrypt sensitive stuff like passwords, keys, PII (Personally Identifiable Information) and images before emailing to known people/groups.
  4. You do that sort of thing with many different people/groups.
  5. You use a different keypair for each person/group.
  6. You're able to organise email address and agreed encryption formats for those recipients into a JSON formatted reference document.
  7. You need a tool that will create encryption commands for you, based on that structured JSON data.
  8. You're basically me.

Anyway, moving on...

The Challenge

I wanted to write a tool that abstacted away some of the predictable details when I issued a gpg command to encypt.

I wanted the challenge of writing a basic tool that could configure and execute a bespoke command, based on these parameters:

  1. Public or Symmetric key encryption.
  2. The defined list of recipients.
  3. The sender identity I was adopting for that communication.

This project was really a solution to my own encryption circumstances.

Clearly, I also wanted a motive to improve my understanding of encryption, the GnuPG (gpg) utility, shell scripting, Git and Github, all on which my sofware tech enthusiast hobby usually depend.

The Solution

Technical and User Documentation

The README document over on Github serves as both technical and user documentation for this project.

Encryption Profiles

{ "profileID": "1", "profileName": "local message encryption", "profileDescription": "profile to public key encrypt local files", "encryptionSystem": "public_key", "outputFileFormat": "ascii", "senderUID": "damola@host0.org", "recipientUIDList": [ "'damola@host0.org'", "'damola@host1.org'" ] }, ...

Why JSON?

Why not YAML or even XML? All are standardised ways to define configuration files. JSON sits between the others for strictness, speed of parsing and ease of use.

The security nature of the project seemed to demand minimal scope for introduction of human error when defining the program's runtime configuration. A validated XML document might therefore have been maximal for that requirement. Only thing was, I'd forgotten how to implement XML, so decided JSON would also be good.

Running the Program

damola@host0:~$ ls | grep astral astral0 astral1 astral2 damola@host0:~$ gpg-file-encrypt.sh astral0 astral1 Which JSON Profile to use for the encryption? Choose an option : 1) local message encryption 3) work team roles 2) project keyfiles dev 4) project UML diagram images > 1 You Selected : local message encryption Keypair identified for sender damola@host0.org OK Keypair identified for recipient damola@host0.org OK Keypair identified for recipient damola@host1.org OK File to encrypt : ./astral0 ===specific encryption command string=== gpg --armor --output ./astral0.ENCRYPTED.asc --local-user damola@host0.org --recipient damola@host0.org --recipient damola@host1.org --encrypt ./astral0 Does that command look good? Encrypt the file? Choose an option : 1) Yes, looks good. Encrypt it. 2) No, Quit the Program > 1 You Selected : Yes, looks good. Encrypt it. Encrypting file... ENCRYPTION SUCCESSFUL. File to encrypt : ./astral1 ===specific encryption command string=== gpg --armor --output ./astral1.ENCRYPTED.asc --local-user damola@host0.org --recipient damola@host0.org --recipient damola@host1.org --encrypt ./astral1 Does that command look good? Encrypt the file? Choose an option : 1) Yes, looks good. Encrypt it. 2) No, Quit the Program > 1 You Selected : Yes, looks good. Encrypt it. Encrypting file... ENCRYPTION SUCCESSFUL. Original plaintext files: ./astral0 ./astral1 Shred the plaintext files? (Best practice). Choose an option : 1) Yes, shred them all. 2) No, Keep them and Quit the Program > 1 You Selected : Yes, shred them all. Attempting Shred... shred: ./astral0: pass 1/1 (random)... shred: ./astral0: removing shred: ./astral0: renamed to ./0000000 shred: ./0000000: renamed to ./000000 shred: ./000000: renamed to ./00000 shred: ./00000: renamed to ./0000 shred: ./0000: renamed to ./000 shred: ./000: renamed to ./00 shred: ./00: renamed to ./0 shred: ./astral0: removed shred: ./astral1: pass 1/1 (random)... shred: ./astral1: removing shred: ./astral1: renamed to ./0000000 shred: ./0000000: renamed to ./000000 shred: ./000000: renamed to ./00000 shred: ./00000: renamed to ./0000 shred: ./0000: renamed to ./000 shred: ./000: renamed to ./00 shred: ./00: renamed to ./0 shred: ./astral1: removed SUCCESSFUL SHRED REMOVAL OF FILE: ./astral0 SUCCESSFUL SHRED REMOVAL OF FILE: ./astral1 The End. damola@host0:~$ ls | grep astral astral0.ENCRYPTED.asc astral1.ENCRYPTED.asc astral2 damola@host0:~$ file astral* astral0.ENCRYPTED.asc: PGP message Public-Key Encrypted Session Key (old) astral1.ENCRYPTED.asc: PGP message Public-Key Encrypted Session Key (old) astral2: ReStructuredText file, ASCII text, with very long lines

Google Cloud

"Software Development is very nice indeed"

Let's discuss this...