How to set up GPG keys on Ubuntu 22.04 for signing Git commits

What is a GPG key?

GnuPG is a tool for secure communication and uses public-key cryptography. In a public-key system, each user has a pair of keys consisting of a private key and a public key. A user's private key is kept secret; it need never be revealed. The public key may be given to anyone with whom the user wants to communicate.

Important Concepts

GnuPG makes use of several cryptographic concepts including symmetric ciphers, public-key ciphers, hybrid ciphers, and one-way hashing.

  • Symmetric ciphers are the ciphers that use the same key for both encryption and decryption.;

  • Public-key ciphers are based on one-way trapdoor functions. A one-way function is a function that is easy to compute, but the inverse is hard to compute. For example, if you have a number made of two prime factors, then knowing one of the factors makes it easy to compute the second. Given a public-key cipher based on prime factorization, the public key contains a composite number made from two large prime factors, and the encryption algorithm uses that composite to encrypt the message. The algorithm to decrypt the message requires knowing the prime factors, so decryption is easy if you have the private key containing one of the factors but extremely difficult if you do not have it.

  • A hybrid cipher uses both a symmetric cipher and a public-key cipher. It works by using a public-key cipher to share a key for the symmetric cipher. The actual message being sent is then encrypted using the key and sent to the recipient. Since symmetric key sharing is secure, the symmetric key used is different for each message sent. Hence it is sometimes called a session key.

  • One-way hashing: A hash function is a many-to-one function that maps its input to a value in a finite set. Typically this set is a range of natural numbers. This means a hash function takes various inputs (like text, numbers, etc.) and converts each into a number from a specific range. Even though there's a huge number of possible inputs, the outputs are limited to this fixed range.

  • A digital signature is the result of applying a hash function to the document. This hash value is a signature and it is encrypted using the signer's private key, and anybody can check the signature using the public key. Another person can check the signature by also hashing their copy of the document and comparing the hash value they get with the hash value of the original document. If they match, it is almost certain that the documents are identical.

GPG Use Cases

GPG keys are widely used in:

  1. Software development for signing code and packages to ensure they are not tampered with.

  2. Software Repository Security: In software development, GPG is used to sign software repositories. This helps ensure that the software and updates users download from these repositories are authentic and have not been tampered with.

  3. Email encryption: Users can encrypt the content of their emails so that only the intended recipient, who possesses the correct private key, can decrypt and read them.

  4. Signing Documents: This signature verifies the identity of the signer and ensures that the document or code has not been tampered with since it was signed.

  5. File Encryption: GPG can encrypt files and directories. This is useful for protecting sensitive data, such as personal information or confidential business documents, especially when transmitting them over insecure networks.

  6. Password Management: Some password managers use GPG for encrypting their password databases, adding an additional layer of security.

  7. Secure Backup: GPG can be used to encrypt data before it is backed up to cloud storage or other remote servers. This ensures that your data remains confidential, even if stored on public or shared servers.

  8. Signing Git commits;

Hands-on Lab Overview

In this hands-on, I will generate a GPG key on the Ubuntu 22.04 system and use it for signing git commits to verify that commits are actually from a trusted source. Then, I will upload the public GPG key to the GitHub account for GitHub to be able to verify a commit author's identity. The commit should appear as Verified in the GitHub UI.

Hands-on Lab

To sign commits, you must configure both your local machine and your GitHub account:

Create a GPG key

  1. Ubuntu 22.04 comes preinstalled with GnuPG. You can verify it by running the command:

     gpg --version
    

  2. Check whether you have an existing GPG key pair on your system running the command:

     gpg --list-keys
    

  3. Generate the GPG key pair running the command:

     gpg --full-gen-key
    
  4. Select the algorithm your key should use, or press Enter to select the default option, RSA and RSA.

  5. Select the key length, in bits. Recommended length: 4096-bit keys.

  6. Specify the validity period of your key. This value is subjective, and the default value is no expiration. To confirm your answers, enter y.

  7. Enter your real name, the email address to be associated with this key (should match a verified email address you use in GitLab or GitHub) and an optional comment:

  8. Enter a strong password, then enter it again to confirm it.

  9. To list your private GPG key, run this command, replacing <EMAIL> with the email address you used when you generated the key:

     gpg --list-secret-keys  --keyid-format LONG  <EMAIL>
    
  10. In the output, identify the sec line, and copy the GPG key ID. It begins after the / character. In this example, the key ID is 8595B83984641457:

    NOTE Private key should never be revealed and kept secret. This lab was run on an AWS EC2 machine, and it will be terminated.

  11. To show the associated public key, run this command, replacing <ID> with the GPG key ID from the previous step:

    gpg --armor --export 8595B83984641457
    

  12. Copy the public key, including the BEGIN PGP PUBLIC KEY BLOCK and END PGP PUBLIC KEY BLOCK lines to add this key to the user settings of your GitHub account.

Associate your GPG key with Git

  1. Configure Git to sign your commits with your key, replacing <KEY ID> with your GPG key ID 8595B83984641457:

     git config --global user.signingkey 8595B83984641457
    

Sign your Git commits

  1. Sign individual Git commits manually. Add -S flag to any commit you want to sign:

     git commit -S -m "My commit message"
    

    Enter the passphrase of your GPG key when asked, push it to GitHub, and check that your commits are verified.

  2. Sign all Git commits (automatically) by default by running this command:

     git config --global commit.gpgsign true
    
  3. Locally for each repository individually (recommended):

     git config commit.gpgsign true
    

References:

  1. The GNU Privacy Handbook

  2. Symmetric ciphers

  3. Public-key ciphers

  4. A hybrid cipher

  5. One-way hashing

  6. Use Cases of GnuPG/PGP

  7. How to sign your git commits in Ubuntu 20.04 and why you need it