Skip to content

Generating GPG Key Pairs

In the GPG key system, you generate a key pair, Public and Private.

The private key content should be kept secret, with restricted access. The passphrase for this key should be kept separately, and maintained in a Vault with restricted access.

The following sections explain how to create and manage the keys.

To properly secure they key generation process, one should do their best to provide extensive amounts entropy on their system. We’ll cover how to do so on Linux.

  • We’re requiring physical hardware. Absolutely No virtualized instances.
  • Check for access to a hardware random number generator (hwrng), ls /dev/hwrng
    • Check loaded kernel modules for rng or random number generator. lsmod | grep rng. This should output something akin to the following:

      tpm_rng 16384 0
      rng_core 16384 2 tpm_rng
      tpm 40960 5 tpm_tis,trusted,tpm_crb,tpm_rng,tpm_tis_core
    • What we’re looking for is a hardware random source, such as the tpm, beyond just rng_core. This may be: intel-rng, amd-rng, tpm-rng, even bcm2708-rng

    • If there are no modules other than rng_core present, then it is likely that you do not have a hardware random generator, or it is not active.

    • Depending on compute hardware, you may have a TPM, but is not active. If the hardware has it, attempt to load the module with sudo modprobe tpm-rng, and check ls /dev/tpm* and ls /dev/hwrng again.

    • If you do have a hwrng, this will need to be activated & tied to the CSPRNG thanks to rngd daemon. This is often provided by the rng-tools packages, and should be started before continuing.

  • If the hardware does not have a hardware RNG, we’ll want to provide extra entropy by creating a lot of extra input/output to feed the CSPRNG in the kernel.
    • Install and activate haveged
    • Be prepared to run a few tasks in the background (using screen, or backgrounding a call)
      • dd if=/dev/<largedisk> of=/dev/null bs=1M will generate extensive amounts of disk read IO, while not impacting any other subsystems.
      • iperf command can be used to create network load.

On a physical OSX machine (not a virtualized instance) it is best to copy a couple of random files to /dev/random to insure that there is enough entropy in the system. It is best to use files that are unique and not generally available. Two to three moderate sized files are sufficient to increase the entropy.

To generate a key pair, a user will need GnuPG, preferably but not required to be version 2.1 or greater.

The following information will need to be provided when generating a key.

  • kind of key you want, which will be (1) RSA and RSA
  • keysize, which will be 4096, not the default of 2048
  • how long the key is valid for, which will be 2y for 2 years.
  • Real Name, which will be GitLab, Inc.
  • Email Address, which will be [email protected]
  • Comment, which will be an empty value, ''

Run gpg --full-generate-key, and provide values as above. You will be prompted for a passphrase, which should be an alpha-numeric combination that is 20+ characters long, such as generated by 1Password.

The result of the above, should result in a brand new key pair, visible as such

pub rsa2048 2017-07-26 [SC] [expires: 2022-07-26]
0000000000000000000000000000000000000000
uid [ultimate] GitLab, Inc. <[email protected]>
sub rsa2048 2017-07-26 [E] [expires: 2022-07-26]

Note: the key id is masked here, as 0000000000000000000000000000000000000000

Once the keys have been generated, you will need to create a public key for publishing, and in PackageCloud. This is completed simply via:

gpg --armor --export <KEYID> > package-sig.gpg

Next, we’ll to export the entire secret key:

gpg --export-secret-key <KEYID> > packages.gitlab.gpg

This key should be uploaded to the secure storage location.

By “extending” keys, we’re actually referring to extending the expire field into the future, thus extending the useful lifespan of the key(s). To extend the signing key pair, one needs access to the original private key and passphrase.

The steps to extend are as follows:

  • Import the original private key, as this should never be kept on a system.

    Terminal window
    gpg --allow-secret-key-import --import packages.gitlab.gpg
  • Confirm the key is imported and accessible with the private key:

    Terminal window
  • Edit the key interactively with gpg:

    Terminal window
    gpg --edit-key <KEYID>
  • Enter expire, follow prompts to expire by X years with 2y

  • At this stage, you will be prompted to the key’s passphrase.

  • Enter key 1 to select the subkey

  • Enter expire, follow prompts to expire by X years with 2y

  • Enter save to store the changes to the key and exit.

  • Export the updated key(s), and upload to appropriate storage locations & systems.

  • Ensure to copy the original key to a backup file in the secure storage location.

Now you can export the keys.

Citing from gpg-announce in 2009’Q1 :

“Anytime you have a key expiring, it is a good time to ask yourself whether it’s time to create a new key or extend the life of the old one. Good reasons to create a new key include using larger key size. Good reasons to continue using your existing key include keeping the signatures on the key so that any trust you’ve built up by others signing your key remains.”

Once one has completed any step here, and have safely uploaded to secure storage, it is very important that they then purge the signing keys off their system.

gpg --delete-secret-key <KEYID>