It always seems that just enough time has passed since the last time I worked with GnuPG for me to forget not just the exact syntax of these commands completely but the workflow in general. Here are some basics about using GnuPG and managing keys. If you need to know more about GnuPG, I would suggest reading Linux Security Cookbook by Daniel J. Barrett et al.
Installing GnuPG
The GnuPG package is installed by default. You verify this and get the version like so:
rpm -qa | grep ^gnupg
Setting up the user environment
This may not be required, but is not a bad idea to add a couple of lines to your ~/.bashrc
:
GPG_TTY=$(tty) export GPG_TTY
Managing GPG Keys
If you run into the gpg: cancelled by user' error
when generating a new key or a certificate, try doing this:
# As the user who is having the issue run the 'tty' command # and note the pts number tty # /dev/pts/1 # Then become root and adjust permissions on that pts: sudo su - root chmod o+rw /dev/pts/1
Make sure you are the user you think you are. I can’t tell you how many times I screwed this up.
su - <username> && id
List existing public and private keys
gpg --list-keys --with-fingerprint && gpg --list-secret-keys --with-fingerprint
Delete any unneeded public or private keys
gpg --delete-key <key_id> gpg --delete-secret-key <key_id>
Change key passphrase
Suppose you need to change the passphrase on an existing key. This only affects the private key. The public key remains unchanged, so you don’t need to re-send it to people.
gpg --edit-key <key_id>
Generate a new GPG key pair
It is a good idea to set an expiration date for your key. The current standard used by many financial institutions is 23 months or less.
cd ~ && gpg --gen-key
Set the key trust level
Because this is your key, set the trust level to 5.
gpg --edit-key <key_id> trust
Export a public key to binary format
This format works well for distributing the key via file-sharing apps like cloud storage, SFTP, etc.
gpg --output gpg_user1_email@domain.com.$(date +'%F').ascii.pub.key --export email@domain.com
Export a public key to an ASCII-armored key file
This format is suitable for sharing via text-centric apps like email, chat apps, etc.
gpg --output gpg_user1_email@domain.com.$(date +'%F').bin.pub.key --armor --export email@domain.com
Create a key revocation certificate
This certificate can be used to revoke a compromised key pair.
# Obtain the secret key ID gpg --list-secret-keys # Create the revocation cert gpg --gen-revoke <key_id> > ~/.gnupg/revocation_<key_id>.crt # Set permissions chmod 600 ~/.gnupg/revocation_<key_id>.crt
Revoking a key
When you revoke a key, this only affects your local machine. You will no longer be able to use this key. But someone else might if they got their hands on your private key (which is probably why you’re revoking the key in the first place). It is therefore important to send your revoked key to a keyserver (see the following section) so that others are aware of your misfortune. This is a flaky process, though, as few people bother using keyservers or are regularly validating keys.
gpg --import ~/.gnupg/revocation_<keyID>.crt gpg --send-keys <key_id>
Using public keyservers
The situation with the public keyservers has traditionally been a mess. Every few years, they seem to come and go. If you’re relying on public keyservers to distribute your keys, you would need to stay on top of this and regularly check the status of any servers you’re using.
Set the default key server
Edit your gpg.conf
and update the keyserver
setting to show keyserver hkps://keys.openpgp.org`
or whatever other keyserver you would like to use as the default. The keyserver can also be specified from the command line using the --keyserver keyserver_address
option.
vi ~/.gnupg/gpg.conf
Verify key server status
You can verify that the keyserver is responding like so:
for i in 80 443; do nc -v -i1 -w1 keys.openpgp.org ${i}; done
Publish your key to a PGP keyserver
gpg --send-keys <key_id>
Search for public keys on a keyserver
The string
can be an email address, key ID, or key fingerprint. The latter is the best option to avoid the confusion of multiple keys associated with the same email address or short vs. long key IDs. Remember that the fingerprint should contain no spaces.
gpg --search-keys <string>
You can use the one-liner below to search the keyserver for all the keys in your local key chain.
for i in $(gpg --list-keys --with-fingerprint | grep fingerprint | awk -F'=' '{print $NF}' | sed 's/ //g'); do gpg --no-tty --search-keys ${i} 2>/dev/null done
Import a key from a keyserver
gpg --recv-keys <key_id>
GPG and SSH keys
GPG is often used to encrypt SSH keys, so this is just a quick overview of this process.
Generate SSH key pair
ssh-keygen -f ~/.ssh/id_rsa_$(date +'%F') -t rsa -b 4096 -C "email@domain.com"
Generate a PGP-signed version of the SSH public key
Similarly to generating signed versions of the PGP public key, you can use binary or ASCII-armored formats.
# Provide the passphraze for the GPG key you're using read -s gpg_password # Output binary format gpg --passphrase "${gpg_password}" --batch --sign -o ~/.ssh/id_rsa_$(date +'%F')_signed_bin.pub ~/.ssh/id_rsa_$(date +'%F').pub # Output ASCII format gpg --passphrase "${gpg_password}" --batch --sign --armor -o ~/.ssh/id_rsa_$(date +'%F')_signed_ascii.pub ~/.ssh/id_rsa_$(date +'%F').pub
Encrypting and decrypting files
Simple file encryption using a password
This encryption method does not use any keys – just a password. This is less secure but, obviously, very convenient.
read -s gpg_passwd gpg --batch --symmetric --quiet --yes --passphrase "${gpg_passwd}" "${file_name}" 2>/dev/null
Simple file decryption using a password
A file encrypted with a password (as shown above) can be decrypted like so:
read -s gpg_password gpg --batch --decrypt --passphrase "${gpg_password}" -z 2 "${file_name}" 2>/dev/null
Encrypt a file using the recipient’s public key
You can use either the recipient’s email address or the key ID as a value for the --recipient
argument.
gpg --output "${file_name}.gpg" --encrypt --recipient "${recipient_email}" "${file_name}"
Decrypt a file using the recipient’s private key
gpg --output /tmp/test_crypt.txt --decrypt /tmp/test_crypt.txt.gpg # Or do this non-interactively read -s gpg_password gpg --batch --passphrase "${gpg_password}" --output "${file_name}" --decrypt "${file_name}.gpg"
Using GPG with logrotate
This is an oddity, but you can use GnuPG with logrotate
to encrypt your rotated log files. Usually, log files are harmless, but not always. On occasion, devs enable verbose logging for troubleshooting purposes. Doing so can leave potentially sensitive data in the log files. If this had happened before, it would happen again.
Here’s an example of a custom /etc/logrotate.d/squid
that uses gpg
to encrypt data during log rotation.
/var/log/squid/*.log { daily rotate 5 compress compresscmd /usr/bin/gpg compressoptions --always-trust --encrypt --recipient your_email@domain.com compressext .gpg notifempty missingok sharedscripts postrotate # Asks squid to reopen its logs. (log_rotate 0 is set in squid.conf) # errors redirected to make it silent if squid is not running /usr/sbin/squid -k rotate 2>/dev/null # Wait a little to allow Squid to catch up before the logs is compressed sleep 1 endscript }
Experienced Unix/Linux System Administrator with 20-year background in Systems Analysis, Problem Resolution and Engineering Application Support in a large distributed Unix and Windows server environment. Strong problem determination skills. Good knowledge of networking, remote diagnostic techniques, firewalls and network security. Extensive experience with engineering application and database servers, high-availability systems, high-performance computing clusters, and process automation.