YAGNI
You are(n't)? gonna need it...
Encrypt data using OpenPGP
About
This post attempts to summarize the most frequent tasks when it comes to encrypting data and managing encryption keys. It focuses on the GNU Privacy Guard (GPG), which is the GNU's implementation of OpenPGP.
All the examples in this post are executed in the command line using the gpg
program. The concepts presented here can be extended to other clients i.e Emacs,
OpenKeyChain, etc.
Managing keys locally
Before starting to encrypt files, it's required first to have some basic knowledge about managing personal key pairs. This section doesn't consider the usage of a key server.
Personal keys
To generate a new key pair (public/private) use the --gen-key command. This
command will suggest sensible defaults for creating the new key pair, it will
also create a "revocation certificate" which is stored in the
.gnupg/openpgp-revocs.d folder.
gpg --gen-key
The created key pair expires in 3 years. To create a key with a different
expiration time or without an expiration date, use the --full-gen-key instead.
For other ways of generating key pairs, see the gpg man page.
View the keys in the keyring
To view the public keys that are available in the keyring use the --list-keys (-k)
command.
gpg -k
An example of the output looks like is:
[keyboxd]
---------
pub ed25519 2025-11-05 [SC] [expires: 2028-11-04]
89AE120CA468BFC9D1B7EA6ECBD8D4A7A5681EDF
uid [ultimate] test <test@test.com>
sub cv25519 2025-11-05 [E] [expires: 2028-11-04]
pub ed25519 2025-11-05 [SC]
BAC76CAB4DD7F0B431104806C5C32C92869510D6
uid [ultimate] test (comment) <test@test.com>
sub cv25519 2025-11-05 [E]
Either the hex ID under the pub line, the name or the email address can be
used to identify a key.
Other people's public keys
To add a public key from a trusted source to your keyring, use the --import
command:
gpg --import persons_trusted_public_key_file
If you know for sure that a public key belongs to the person who claims it,
then it's possible to sign it; this action will let gpg know that you trust the
key. The public key can be signed by issuing the --sign-key command.
gpg --sign-key key_identifier
Note: Refer to the previous section to see how to extract the key's identifier
using gpg -k.
Encrypt
Now that we have basic knowledge about how manage the keyring, we can proceed to explore the encryption step. For encrypting data there is one command and a few relevant options to know about:
- --encrypt (-e): This command tells
gpgthat we intend to encrypt data. It takes an optional filename as an argument, this name refers to the file that will be encrypted. If no filename is provided, then it reads the data from the standard input. - --recipient (-r): This option takes one argument, which is the key identifier of the recipient to whom the data is to be encrypted. It is possible to use this option multiple times in a single command if the encrypted message is intended for more than one person.
- --armor (-a): This switch is optional and it tells
gpgto use readable ASCII to represent the encrypted data rather than using the default OpenPGP's binary format. - --sign (-s): This switch is also optional and requests that the encrypted data is to be signed with our key. With this signature, the recipient can verify that the encrypted message comes from the person who claims to be the sender.
Messages
Now that we know about the relevant command line options for encrypting data, we can proceed to encrypt a message.
For this task, we just need to know that if the --encrypt command didn't take
a filename as an argument, then it will read its input from STDIN and that the
encrypted data will be sent to STDOUT. This means that in order to encrypt a
message it should be enough to redirect the standard input and output as in:
gpg --recipient Ritchie --recipient Buddy --armor --encrypt <<END > encrypted.txt.asc
Let's rock!!
<<END
Files
Given the previous section, we now know that we can pass a filename to the
--encrypt command, the file will be processed and a resulting encrypted file
will be generated. The following example is similar to the previous one, but it
uses the options' short names, note that it includes multiple recipients.
gpg -r Ritchie -r Buddy -r Me -sae rocknroll.txt
When the --armor (-a) option is used, the resulting file has an extension
asc (ASCII), otherwise the file extension is gpg (OpenPGP binary format).
Decrypt
Use the --decrypt (-d) command to decrypt a message. This command takes an
optional argument which is the name of the file that is to be decrypted; if this
argument is missing, then the encrypted data is read from the STDIN.
The decrypted data is written to STDOUT unless the --output (-o) option is
used, i.e:
gpg -o rocknroll.txt -d rocknroll.txt.asc
Important
- If you encrypt a file and you don't include yourself as a "recipient" then you won't be able to decrypt it.
- It's possible to "sign" data without encrypting it by using the
--sign (-s)command. - The signature can be detached from the data by using the
--detach-sign (-b)command. - The
--verifycommand is used to verify the signature. - People use
openpgpkey servers to share public keys. If one of this servers is to be used, make sure that you select a server that is reliable and follow the practices for verifying and trusting public keys. - If a key is compromised and/or needs to be removed, then it's important to "revoke" it. In a previous section, it was mentioned that a revocation certificate is created at the time of generating a new key pair, this certificate can be used to revoke the key, refer to the next section.
- To delete a key, you may use the
--delete-keysor--delete-secret-and-public-keycommands.
See also
- The gpg man page
- The Key server article in Wikipedia
- The GPG Tutorial by DigitalOcean
- How to revoke a key
