In the development life cycle, there are a number of points where it is useful to have a published public key. Examples include build signing, Git commit signing, and communicating with other community members securely. Build signing in particular is a required part of the release process for the Celo blockchain client.
In support of these uses, OpenPGP public keys can be published to celo.org, where they can downloaded securely by anyone.
If you want to read more about OpenPGP keys, including their structure and metadata, check out Anatomy of a GPG Key by Dave Steele.
Note: This guide assumes you have an @clabs.co email address, but if you do not, simply change the email domain to your primary developer email (e.g. @example.com for [email protected]) Some additional setup will be required in the DNS records for your domain to configure OpenPGP WKD.
GnuPG, or gpg
, is by far the most popular implementation of OpenPGP, and it is what we will be using here.
Install gpg
on MacOS with Homebrew using brew install gpg
or visit gnupg.org/download for other options.
In this guide, a couple of environment variables are used in the commands. Set the following for convenience:
export USER_NAME='your name on the clabs.co email domain. e.g. alice for [email protected]'
export REAL_NAME='your first and last name. e.g. Alice Turing'
OpenPGP supports a number of cryptographic algorithms including RSA and ECC.
Here we recommend secp256k1
, which is the algorithm underlying identity on the Celo blockchain, because it is fast, secure, and promotes interoperability within the Celo ecosystem. (e.g. Your OpenPGP key could be used to take actions on-chain, which is pretty neat.)
Note: When using a YubiKey with firmware version less than 5.2.3,
secp256k1
is not available. Instead, we recommend usingrsa2048
. Github does have limited support for signing algorithms.
In OpenPGP, each key is associated with a user identity, which is commonly an email address and your name (e.g. "Alice Turing [email protected]"). A public key created by gpg
will automatically include the username, in addition to the cryptographic public key information, so when someone downloads your public key, they will know it is intended for your email address.
By publishing keys on celo.org, users can securely download developer keys from their @clabs.co
email address, and know that it is the correct one because publishing to celo.org requires approval of the Celo core developers.
We recommend generating your developer key pair with a YubiKey. Generating your key on a YubiKey provides higher security by making it virtually impossible for an attacker to steal your private key by hacking your computer.
Warning: Losing your YubiKey will result in the permanent loss of any keys stored on it. It is not possible to create a backup of a private key created with this method.
Note: When asked for the admin PIN, it is 12345678 by default. If asked for the user PIN, it is 123456 by default.
- Insert the YubiKey into the USB port.
- Run
gpg --card-edit --expert
- At the
gpg/card>
prompt, enter the following commands:admin
key-attr
2
to selectECC
on the signature key.9
to selectsecp256k1
on the signature key.- Repeat this selection for the encryption and authentication keys.
generate
- When asked if you want to backup your encryption key, specify
n
for no. - Specify an expiration date, for example
2y
for 2 years. - Enter you full name and
@clabs.co
email address when prompted. - You may add a comment, but it is not required.
- When asked if you want to backup your encryption key, specify
quit
See the official YubiKey documentation for more information.
Use the following command, replacing the environment variables, to generate a new key on your machine:
gpg --quick-generate-key "${REAL_NAME} <${USER_NAME}@clabs.co>" secp256k1
You now have a secret key and public key, on secp256k1
and with a 2 year expiration, associated with your @clabs.co
email address.
See man gpg
for more information on key generation options.
If you've generated a key on your local machine, it can be imported onto your YubiKey with the following steps.
Note: When asked for the admin PIN, it is 12345678 by default. If asked for the user PIN, it is 123456 by default.
- Insert the YubiKey into the USB port.
gpg --edit-key ${USER_NAME}@clabs.co
- At the
gpg
prompt enter the following commands:keytocard
and select1
to set the signature key on the YubiKey.keytocard
and select3
to set the authentication key on the YubiKey.quit
and save your changes.
See the official YubiKey documentation
Use the following command as a quick way to verify that your new key can be used to produce a valid signature:
gpg -u ${USER_NAME}@clabs.co -o - --sign <(head -c 256 /dev/urandom) | gpg --verify -
Note: The command above works by signing 256 bytes of random data with your new key, then verifying the signature over that data.
You should see Good signature from ...
with your real name and email.
Keys are published to celo.org using OpenPGP WKD, which is essentially just a hosted folder of public keys. Published keys are managed by submitting a pull request to the https://github.com/celo-org/website repo on Github.
Adding your key to https://github.com/celo-org/website repo will allow it to be available on celo.org with the next website deployment.
After cloning the repo, running the following command from the root of website
will add your key to the openpgpkey
directory:
gpg --list-options show-only-fpr-mbox -k ${USER_NAME}@clabs.co | $(gpgconf --list-dirs libexecdir)/gpg-wks-client -v --install-key -C openpgpkey
You should confirm that a new key file was added to the openpgpkey/
directory and open a pull request with the change. You should see the new file in the openpgpkey/clabs.co/hu
folder, if you followed the directions above.
Once a new version of celo.org is published, you will be able to verify your keys are published correctly with the key lookup instructions below.
Users can lookup keys on the @clabs.co
domain with the following command:
gpg --auto-key-locate wkd --locate-external-keys ${USER_NAME}@clabs.co
This command will query clabs.co over HTTPS and retrieve the latest key for ${USER_NAME}@clabs.co
.
If you want to check a key is correctly hosted, or want to fetch a key manualy for some reason, you can do so with:
curl https://openpgpkey.clabs.co/.well-known/openpgpkey/clabs.co/hu/$USER_HASH
$USER_HASH
can be obtained by observing the output of the WKD utility. It is the filename of the resulting key file that is added to the website repsitory for publishing. It can also be calculated directly following the specification in the WKD specification, draft-koch-openpgp-webkey-service, section 3.1. (Warning: It uses an obscure varient of base32 :| )
A signature can be produced over a document with a number of options using gpg
.
Use the following command to produce an ASCII encoded detached signature with your @clabs.co
key:
gpg -u ${USER_NAME}@clabs.co -o doc.txt.asc --armor --detach-sign doc.txt
This command will produce the signature file doc.txt.asc
for doc.txt
. The signature file can be distributed along side the document, and be verified by any user with access to the document and your public key.
A signature file produced with the method above can be verified by any user that possesses your public key with the following command.
gpg --verify doc.txt.asc doc.txt
See the gpg
manual entry on signatures for more information.