How to Sign Our Git Commits with GPG

Hello!

Today, let's talk about signing a git commit with GPG, an encryption engine for signing and signature verification.

When it comes to work across the Internet, it's recommended that we add a cryptographic signature to our commit, which provides some sort of assurance that a commit is originated from us, rather than from an impersonator.

This blog is based on the following environments:

  • Windows 10 x64-based
  • Ubuntu 20.04 LTS, Windows Subsystem Linux (WSL) version 2

1. Preparations

In this section, we will install GPG, and config it.

Installation

1$ sudo apt-get install gnupg

And it's done. Next, we have to configure it.

Firstly, we will append these two lines to the profile file. In this case, I am using bash. So I will open ~/.bashrc, and append:

1export GPG_TTY=$(tty)
2gpgconf --launch gpg-agent

After saving these contents, we will go to the terminal, and type this command to validate settings:

1$ source ~/.bashrc

And the GPG is ready to go.

2. Configurations

2.1 Generate a GPG Key Pair

Just type this command:

1$ gpg --full-gen-key

Note:

  1. What kind of key you want: RSA and RSA (default)
  2. What keysize do you want: 4096
  3. How long the key should be valid: 0 (key does not expire)
  4. Is this correct: Y
  5. Real Name: (Your GitHub Name)
  6. E-mail: (Your GitHub Email), and it MUST MATCH your GitHub account !!!
  7. Comment: (Leave your note for that key)

2.2 Add Public Key to GitHub Settings

Now that the keys are generated, we need to add the Public Key to GitHub Setting pages.

To fill in the contents, we go back to the Terminal, and type these commands to get GPG Public Key:

 1# (1) List all the keys
 2$ gpg --list-secret-keys --keyid-format=long
 3
 4# And it shows the following contents: (* hidden for privacy)
 5#    sec   rsa4096/********** 2022-05-20 [SC]
 6#          ED0BEFAC1E5C4681F0A0FEF0E97461039812B753
 7#    uid                 [ultimate] Mighten Dai <mighten@outlook.com>
 8#    ssb   rsa4096/********** 2022-05-20 [E]
 9
10# (2) Display the associate Public Key
11$ gpg --armor --export ED0BEFAC1E5C4681F0A0FEF0E97461039812B753 # copy from above

and this command will shows the required Public Key like that:

1-----BEGIN PGP PUBLIC KEY BLOCK-----
2
3.........
4-----END PGP PUBLIC KEY BLOCK-----

In SSH and GPG Keys of your GitHub Settings, click New GPG Key, and it prompts Begins with '-----BEGIN PGP PUBLIC KEY BLOCK-----', which exactly is the contents above.

2.3 Associate with Git

In Section 2.2, my Private Key shown as 'ED0BEFAC1E5C4681F0A0FEF0E97461039812B753', so I just open the configuration file ~/.gitconfig and change the following properties:

1[user]
2    name = Mighten Dai
3    email = mighten@outlook.com
4    signingKey = ED0BEFAC1E5C4681F0A0FEF0E97461039812B753
5[commit]
6    gpgsign = true
7[gpg]
8    program = /usr/bin/gpg

And it's done.

3. Git Commit with GPG

1$ git add .
2$ git commit -S -m "This is a commit with PGP Signature"

4. (Optional)

In this section, we talk about other usage of GPG

4.1 Sign & Verify Plaintext

If you just want to sign a plaintext, you just type with a Pipe command | like this:

1echo "Signing a plaintext" | gpg --clearsign

and it immediately shows:

 1-----BEGIN PGP SIGNED MESSAGE-----
 2Hash: SHA512
 3
 4Signing a plaintext
 5-----BEGIN PGP SIGNATURE-----
 6
 7iQIzBAEBCgAdFiEE7QvvrB5cRoHwoP7w6XRhA5gSt1MFAmRxbSoACgkQ6XRhA5gS
 8t1OfvA/+IGNwwCfJmwkb2LjhUQgACcUedCS6/VGb7uek7PQwQJr6Aid4hp7cguVz
 9lfGpadKTi6chokwcRgwjjuaCd/DFabaHs5e03Q2nn8qqE5Gx+chNcG/+9/cuDRxa
10JnyEiqTUY62UIGY6+WVYgKE/+T3CpRX3wdLYC3n0InyctdJZNIIycX/IragUhXAh
11VSZc66QxA60zgNFXzypMyl8NfxmDQKdE8IkCOgiPgHhat0dDQxQQd6zqSmTdQM8P
12OXpLpT0ryXI9ZnqkOk/gN9mUrncpilelE2J6NgMKbe0lOGNP45F9GQMxqVUQqw/1
13i6rCTV4gLR+Xmfaydo9fFj5p5mB7VK8IPZGh5Q7RM722D4NxJfaIekhlD1Sy32cP
14wp0581fHLk778ngz6jomNt/srND5xf13cStdHSxSMwHS8PXxyh5rUs5KtTDH7srg
15U19l8rdgr9TBl6/ydBlL0aepGQW95KA0loxW2mwrpsEG8Ii1fZ2kMWqR17dPxwoe
167O3BbeGW0k9Ur3MSm8m5jP2OKvDm62cMiLnUYP3LKakKGL4PBeer26NWK+4dXhi6
170/ohXd7GGa1zuhChFwj0/pqzjYU2PQLUUOb1/UXKXmpGvu/GvGvZ1Slu0VOKUVil
18dXv1cxUHgINY6CvoCdH6gxuKmz1K4B8TXqZ4wzMj4FLx/10PtPk=
19=tIWQ
20-----END PGP SIGNATURE-----

And if some guy send you these thing, you can verify by:

1$ gpg --verify signedMsg.txt
2gpg: Signature made Fri May 20 15:51:09 2022 CST
3gpg:                using RSA key ED0BEFAC1E5C4681F0A0FEF0E97461039812B753
4gpg: Good signature from "Mighten Dai <mighten@outlook.com>" [ultimate]

It seems that this message is good. What if we want to tamper with this message

1$ gpg --verify signedMsg-tampered.txt
2gpg: Signature made Fri May 20 15:51:09 2022 CST
3gpg:                using RSA key ED0BEFAC1E5C4681F0A0FEF0E97461039812B753
4gpg: BAD signature from "Mighten Dai <mighten@outlook.com>" [ultimate]

So, now we can see the bad message detected.

4.2 Verify Online Files

In this section, I will verify the integrity of online files.

I have downloaded the file gnupg-2.4.2.tar.bz2.sig and its signature file gnupg-2.4.2.tar.bz2, I can verify by:

 1# 1. acquire Public Key of the publisher, 
 2#      e.g., https://gnupg.org/signature_key.html
 3$ gpg --import  public_key.asc
 4...
 5gpg: Total number processed: 4
 6gpg:               imported: 4
 7gpg: marginals needed: 3  completes needed: 1  trust model: pgp
 8gpg: depth: 0  valid:   1  signed:   0  trust: 0-, 0q, 0n, 0m, 0f, 1u
 9
10# 2. verify the file
11$ gpg --verify gnupg-2.4.2.tar.bz2.sig  gnupg-2.4.2.tar.bz2
12gpg: Signature made 5/30/2023 8:27:44 PM China Standard Time
13gpg:                using EDDSA key 6DAA6E64A76D2840571B4902528897B826403ADA
14gpg: Good signature from "Werner Koch (dist signing 2020)" [unknown]
15...
16
17# 3. List all the keys
18$ gpg --list-keys
19
20# 4. Delete keys that are temporarily imported
21$ gpg --delete-key  < The keyID you want to delete >

* This blog was last updated on 2022-05-20 13:54