As we all know, today more than ever before, it is crucial to be able to trust our computing environments. One of the main difficulties that package maintainers of GNU/Linux distributions face, is the difficulty to verify the authenticity and the integrity of the source code. With GPG signatures it is possible for packagers to verify source code releases quickly and easily.
- Create and/or use a 4096-bit RSA keypair for the file signing
- Use a strong, unique, secret passphrase for the key
- Upload the public key to a key server and publish the full fingerprint
- Sign every new Git commit and tag
- Create signed, compressed (xz --best) release archives
- Upload a strong message digest (sha512) of the archive
- Configure HTTPS for your download server
GPGit is meant to bring GPG to the masses. It is not only a Python script that automates the process of creating new signed Git releases with GPG, but also a quick-start-guide for learning how to use GPG. GPGit integrates perfectly with the Github Release API for uploading.
The security status of GNU/Linux projects will be tracked in the Linux Security Database. If you have any further questions, do not hesitate to contact me personally. Thanks for your help in making GNU/Linux projects more secure by using GPG signatures.
You can install GPGit from AUR. Make sure to build in a clean chroot. Please give the package a vote so I can move it to the official ArchLinux [community] repository for even simpler installation.
GPGit dependencies can be easily installed via pip.
# Install dependencies
sudo apt-get install python3 python3-pip gnupg2 git
VERSION=2.0.7
# Download and verify source
wget https://github.com/NicoHood/gpgit/releases/download/${VERSION}/gpgit-${VERSION}.tar.xz
wget https://github.com/NicoHood/gpgit/releases/download/${VERSION}/gpgit-${VERSION}.tar.xz.asc
gpg2 --keyserver hkps://pgp.mit.edu --recv-keys 97312D5EB9D7AE7D0BD4307351DAE9B7C1AE9161
gpg2 --verify gpgit-${VERSION}.tar.xz.asc gpgit-${VERSION}.tar.xz
# Extract and install dependencies
tar -xf gpgit-${VERSION}.tar.xz
cd gpgit-${VERSION}
pip3 install --user -r requirements.txt
# Install and run GPGit
sudo cp gpgit.py /usr/local/bin/gpgit
gpgit --help
The script guides you through all 5 steps of the GPG quick start guide. By default no extra arguments beside the tag are required. Follow the instructions and you are good to go.
Show help message and exit.
Show program's version and exit.
Tagname of the release. E.g. 1.0.0
or 20170521
with $(date +%Y%m%d)
.
Use the given as the commit message.
Output path of the archive, signature and message digest. You can also set this option via configuration.
Path to the Git project.
Disable Github API functionality. Github releases need to be created manually and release assets need to be uploaded manually. GPGit will not prompt for a Github token anymore.
Flag as Github prerelease.
Additional configuration can be made via git config. Example usage:
git config --global gpgit.token <token>
git config --global gpgit.output ~/gpgit
git config --local gpgit.compression gzip
Full GPG fingerprint to use for signing/verifying.
Output path of the archive, signature and message digest. You can also set this option via parameter.
Archive compression option. Chose between "gzip,xz,bzip2,lzip". Default: "xz"
Message digest algorithm. chose between "sha256,sha384,sha512". Default: "sha512"
Keyserver to use for GPG key check. Automatically set to "skip" after the first check was successfull. Default: "hkps://pgp.mit.edu"
Enable or disable Github functionality with "true|false". Default: "true" (enabled)
Username used for github uploading.
Project name used for github uploading and archive naming.
Use ascii armored output of GPG (.asc instead of .sig) with "true|false". Default: "true" (armored output).
Specify the Github token for Github API release uploading.
GPGit guides you through 5 simple steps to get your software project ready with GPG signatures. Further details can be found below.
- Generate a new GPG key
- Publish your key
- Use Git with GPG
- Create a signed release archive
- Upload the release
Make sure that your new passphrase for the GPG key meets high security standards. If the passphrase/key is compromised all of your signatures are compromised too.
Here are a few examples how to keep a passphrase strong but easy to remember:
If you don't have a GPG key yet, create a new one first. You can use RSA (4096 bits) or ECC (Curve 25519) for a strong key. The latter one does currently not work with Github. You want to stay with RSA for now.
Make sure that your secret key is stored somewhere safe and use a unique strong password.
Crucial key generation settings:
- (1) RSA and RSA
- 4096 bit key size
- 4096 bit subkey size
- Valid for 1 year (1y)
- Username and email
$ gpg --full-gen-key --expert
[...]
gpg: /tmp/trustdb.gpg: trustdb created
gpg: key 61D68FF6279DF9A6 marked as ultimately trusted
gpg: directory '/tmp/openpgp-revocs.d' created
gpg: revocation certificate stored as
'/tmp/openpgp-revocs.d/3D6B9B41CCDC16D0E4A66AC461D68FF6279DF9A6.rev'
public and secret key created and signed.
pub rsa4096 2017-01-04 [SC] [expires: 2018-01-04]
3D6B9B41CCDC16D0E4A66AC461D68FF6279DF9A6
3D6B9B41CCDC16D0E4A66AC461D68FF6279DF9A6
uid John Doe <john@doe.com>
sub rsa4096 2017-01-04 [E] [expires: 2018-01-04]
The generated key has the fingerprint 3D6B9B41CCDC16D0E4A66AC461D68FF6279DF9A6
in this example. Share it with others so they can verify your source. [Read more]
If you ever move your installation make sure to backup ~/.gnupg/
as it contains the private key and the revocation certificate. Handle it with care. [Read more]
To make the public key widely available, upload it to a key server. Now the user can get your key by requesting the fingerprint from the keyserver: [Read more]
# Publish key
gpg --keyserver hkps://pgp.mit.edu --send-keys <fingerprint>
# Import key
# Alternative keyserver: hkps://hkps.pool.sks-keyservers.net
gpg --keyserver hkps://pgp.mit.edu --recv-keys <fingerprint>
To make it easy for everyone else to find your key it is crucial that you publish the full fingerprint on a trusted platform, such as your website or Github. To give the key more trust other users can sign your key too. [Read more]
To make Github display your commits as "verified" you also need to add your public GPG key to your Github profile. [Read more]
# List keys + full fingerprint
gpg --list-secret-keys --keyid-format LONG
# Generate public key
gpg --armor --export <fingerprint>
In order to make Git use your GPG key you need to set the default signing key for Git. [Read more]
# List keys + full fingerprint
gpg --list-secret-keys --keyid-format LONG
git config --global user.signingkey <fingerprint>
To verify the Git history, Git commits needs to be signed. You can manually sign commits or enable it by default for every commit. It is recommended to globally enable Git commit signing. [Read more]
git config --global commit.gpgsign true
Git tags need to be created from the command line and always need a switch to enable tag signing. [Read more]
# Creates a signed tag
git tag -s mytag
# Re-tag an older, unsigned tag
git tag -sf mytag mytag
# Verifies the signed tag
git tag -v mytag
You can use git archive
to create archives of your tagged Git release. It is highly recommended to use a strong compression which is especially beneficial for those countries with slow and unstable internet connections. [Read more]
# .tar.gz
git archive --format=tar.gz -o gpgit-1.0.0.tar.gz --prefix gpgit-1.0.0 1.0.0
# .tar.xz
git archive --format=tar --prefix gpgit-1.0.0 1.0.0 | xz > gpgit-1.0.0.tar.xz
# .tar.lz
git archive --format=tar --prefix gpgit-1.0.0 1.0.0 | lzip --best > gpgit-1.0.0.tar.xz
# Verify an existing archive
git archive --format=tar --prefix gpgit-1.0.0 1.0.0 | cmp <(xz -dc gpgit-1.0.0.tar.xz)
Type the filename of the tarball that you want to sign and then run:
gpg --digest-algo SHA512 --armor --detach-sign gpgit-1.0.0.tar.xz
Do not blindly sign the Github source downloads unless you have compared its content with the local files via diff.
[Read more]
To not need to retype your password every time for signing you can also use gpg-agent.
This gives you a file called gpgit-1.0.0.tar.xz.asc
which is the GPG signature. Release it along with your source tarball and let everyone know to first verify the signature after downloading. [Read more]
gpg --verify gpgit-1.0.0.tar.xz.asc
Message digests are used to ensure the integrity of a file. It can also serve as checksum to verify the download. Message digests do not replace GPG signatures. They rather provide and alternative simple way to verify the source. Make sure to provide message digest over a secure channel like https.
sha512 gpgit-1.0.0.tar.xz > gpgit-1.0.0.tar.xz.sha512
Create a new "Github Release" to add additional data to the tag. Then drag the .tar.xz .sig and .sha512 files onto the release.
The script also supports uploading to Github directly. Create a new Github token first and then follow the instructions of the script.
How to generate a Github token:
- Go to "Settings - Personal access tokens"
- Generate a new token with permissions "public_repo" and "admin:gpg_key"
- Store it safely
You can also use your GPG key for email encryption with enigmail and thunderbird. [Read more]
You can get securely in touch with me here. Don't hesitate to file a bug at Github. More cool projects from me can be found here.
2.0.7 (27.06.2017)
* Switch to Python3 from bash
* New user interface with preview
* More verification
* Better GPG usage
* More parameters
* Configurable settings via git config
* Better error traces
* Resigning a tag is now possible
* General improvements
* New logo
* Improved documentation
1.2.0 (24.04.2017)
* Trap on errors
* Detect gpg2
* Fix Git tags pull/push
* Small code fixes
* Thanks @cmaglie with #3
1.1.2 (22.01.2017)
* Fixed Github uploading name
1.1.1 (17.01.2017)
* Verify existing signatures
* Added upload to Github functionality
* Only allow secure GPG keys
1.1.0 (13.01.2017)
* Added online source download
* Added source verification
* Added multiple compression algorithms
* Added multiple sha algorithms
* Minor fixes
* Updated Readme
1.0.0 (07.01.2017)
* Merged all scripts into gpgit.sh
* First release with all functions working except the uploading
Untagged Release (16.12.2016)
* Initial release of the software