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.
< padaProject 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
- You use the Linux command line.
- 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, ...
- 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.
- You do that sort of thing with many different people/groups.
- You use a different keypair for each person/group.
- You're able to organise email address and agreed encryption formats for those recipients into a JSON formatted reference document.
- You need a tool that will create encryption commands for you, based on that structured JSON data.
- 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:
- Public or Symmetric key encryption.
- The defined list of recipients.
- 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