Oh GPG
To encrypt and decrypt my secret messages on my box I use GPG. This post is hopefully going to jog the memory of senile future me (or just future me on a day on which I happen to be hammered and need to perform this trick). Perhaps there is something here that may be of any use to other folks as well :beer:.
Get Started
In order to start using GPG one needs generate a public and secret keys. The public key may be shared with the whole world and will allow others to encrypt messages intended for the holder of the secret key. Once a message is encrypted a secret key is required to decrypt the message which is why one is to take the protection of its secret key seriously. Start generating a GPG keypair by running the following command:
gpg --gen-key
Remember to set a passphrase for the pair. Often enough the keys are used to sign documents so remember that it is often a means for authenticating a user. Unless a passphrase is set, it is very easy for anyone who acquires the secret key to impersonate the identity associated to the key. With a proper passphrase set the party acquiring the key still needs to figure out what the passphrase is and depending on the type of key it may take them some time.
Encrypting
In order to lock up a certain piece of information we can simply pipe it into
the gpg
tool and instruct it how to encrypt it and where to store the
ciphertext. To get started a file is created with the following shell command
that contains the text launch codes
:rocket:.
echo "launch codes" > code.in.txt
The following command basically encrypts the string in the message file and
stores the ciphertext into the file cipher.gpg
. The recipient
vid@bina.me
has been specified in order to instruct whom is to be able
to decrypt the ciphertext. For the encrypted launch codes the given recipient
will be the only person who needs to know so… yeah… secrets
should be encrypted not just chown
ed :closed_lock_with_key:.
cat code.in.txt | gpg -e -r vid@bina.me -o cipher.gpg
Provided that the document needs to be sent to a few third parties of which we happen to have the public key one can include them as recipients. The following example
cat code.in.txt | gpg -e \
-r harold@finch.me \
-r elliot@allsafe.secure \
-o cipher.gpg
Decrypting
Now that the ciphertext is generated one may decrypt it with gpg
as well.
gpg -d cipher.pgp > code.out.txt
Now the launch codes are known and available in code.out.txt
. API keys are
launch codes anyways :wink:.
Signing
One of the uses of GPG is signing. Signing basically computes a digital artefact which may be used to confirm if the document in question is exactly as it was intended to be received by the signing party. If the document is modified the verification of the signature to the document will fail.
There are different ways to handle the signing problem. The documents can be
- wrapped inside a compressed envelope containing the message and signature
- wrapped inside a clear text envelope containing the message and signature
- complemented by a signature in a separate file
Compressed Envelope
The simplest sign operation will wrap the message inside an envelope which is subsequently compressed.
gpg --sign code.txt
Because the output of the regular sign operation leads to a compressed binary
file one would do itself a service to not view it with a text editor or pager,
but with a hex editor. In case xxd
is installed one can view the output with
a hex editor like xxd
.
xxd code.txt.sig
Clear Text Envelope
In case one needs the message in clear text in order to be posted as the body of an email or web post one could choose to ensure the output is just the uncompressed ASCII-armored signature.
gpg --clearsign code.txt
Separate Signature
In some cases one may want the signature separate from the message, in that
case one may use the --detach-sign
argument.
gpg --detach-sign code.txt
Verifying
Verifying of a signed document is performed by:
gpg --verify code.txt.sign
In case a seperate signature is available for a given message, one should specify both files in the verify call as such:
gpg --verify code.txt.sig code.txt
The Agent
Sometimes one may fire up an application that may need to make multiple request for input from encrypted resources. Supposing a passphrase is used, the prompt could be presented every time the encrypted content is consulted.
The agent allows you to enter the passphrase once for a certain duration in which is remembers and and handles the passphrase dance for as long as the passphrase happens to persist in the cache. In the case of mutt that might mean happy mailing without having to enter a passphrase every time a call is made. Pretty sweet :smile:.
The entire agent business works in the following manner:
- invoke the agent daemon (which runs in the background, presents the passphrases for keys it has stored in cache and prompting you for the passphrase it hasn’t yet stored)
- set up a terminal to act as the front-end
Simplified
In order to simplify this entire process I have written a small shell script to handle all of the daemon summoning and front-end spawning work.
Running start-gpg-agent
checks if the info file doesn’t yet exist and
then spawns the daemon.
Basically I use the helper make-gpg-tty
to configure my current terminal
as the GPG-Agent front-end. Mind you that you should only configure one
terminal as the front-end in order to avoid weird :shit:.
That is why make-gpg-tty
stores the agent terminal number to a file and
only links the current terminal as the front-end if there has not already been
another terminal linked for this chore.
In order to disconnect my current terminal I can use unmake-gpg-tty
and
if I want to stop the GPG-Agent I could run stop-gpg-agent
.