GPG guide

Tags: en blog linux tutorial gpg

PGP (Pretty Good Privacy) keys are not used by many, I think it is because they are difficult to grasp. During the years I have struggled too trying to understand them and these are the notes I took during this time. Hope they will give you an easier time than mine with this awesome keys!


  • SCEA
Constant              Character


  • other symbols:

    • # secret key not present
    • > stub present (probably on smart card)
  • extensions

    • gpg/pgp might be used for binary files
    • asc is generally used for armored files
  • info on the stored keys gpg-connect-agent 'keyinfo --list' /bye

    • meaning of the above informations gpg-connect-agent 'help keyinfo' /bye

Create a key

We can either input every value interactively or prepare a text file and load that. We are gonna explore both the methods.

semi-automatic key creation

note: “Key-Lenght:” has to be copied from the reference web page, else might not work, I think because of UTF-8.

  • Edit this script to suit your needs and save it somewhere safe for execution (if writing the password on it)
  %echo Generating a basic OpenPGP key
  Key-Type: RSA
  Key-Length: 4096
  # specify usage if want to limit to Cert only
  Key-Usage: cert
  Subkey-Type: RSA
  Subkey-Length: 4096
  # specify usage if want limit the usage only to encryption
  Subkey-Usage: encrypt
  Name-Real: name
  Name-Comment: comment
  Name-Email: [email protected]
  Expire-Date: 0
  # If passphrase is commented out, it will prompt for password
  #Passphrase: abc
  # Do a commit here, so that we can later print "done" :-)
  • kill the agent if running gpgconf --kill gpg-agent

  • generate the key by using the script gpg --batch --full-generate-key <script>

  • Create other subkeys as needed on --edit-keys as detailed in the manual section of this guide.

  • handy continued-generation from the GNUPGHOME (let’s say we don’t like the numbers) rm -r ./* && gpgconf --kill gpg-agent && gpg -K && gpg --batch --full-generate-key ../script

or from a level above the .gnupg directory

rm -r .gnupg && gpgconf --kill gpg-agent && mkdir .gnupg && chmod 700 .gnupg && gpg -K && gpg --batch --full-generate-key ../script

Interactive key creation (manual method)

  • create a directory in a safe place, ideally you would do it in a live and offline system, but also a tmpfs (ramdisk) could do it, just be sure not to save on an unencrypted directory and/or a compromised computer.

  • kill the agent if running, just in case as it might interfere gpgcong --kill gpg-agent

  • set the GNUPGHOME in there with export GNUPGHOME=/secure/path/.gnupg

  • generate the key gpg --full-generate-key

  • enter edit mode to continue gpg --edit-key <key>

    • downgrade the SC (Sign + Certify) key into C only change-usage
    • add more than one uuid if needed (emails) adduid
    • create Sign and Encryption subkeys (RSA to have 4096) addkey
    • set the trust for your keys to Ultimate, after verifying that you is actually… you. select the UID (an asterisk will appear) uid <n> and set the trust level trust
  • Authentication and other types of keys can also be created, but we need to be in expert mode gpg --expert --edit-key <key>

    • create a key addkey
    • set the capabilities RSA (set your own capabilities)
  • export the keys

    • secret key gpg --export-secret-keys <key> > <destination>.pgp
    • secret subkey gpg --export-secret-subkeys <subkey> > <destination>.pgp
    • secret subkey striped (exclamation point after the key, it reduces the size of it and /stripes/ it from the private master key) gpg --export-secret-subkeys <subkey>! > <destination>.pgp
    • revocation certificate (automatic if no expiration, is a .rev file) gpg --armor --gen-revoke <key> > <destination>.rev
    • export the public key in armored version gpg --export --armor --output <name>.pub
    • export the trust store (cleartext) gpg --export-ownertrust > <destination>.asc
    • export for print using the Dark Otter approach
        gpg --output public.pgp --export SOMEKEYID && \
        gpg --output - --export-secret-key SOMEKEYID |\
            cat public.pgp - |\
            gpg --armor --output keys.asc --symmetric --cipher-algo AES256
      sourced from
  • ssh key handling to use the Auth subkey as ssh key. (more to explore on )

    • conversion from gpg format to ssh’s pub gpg --export-ssh-key <subkey>! > .ssh/<ssh_key_name>.pub
  • Publish the keys

    • verify the UID (emails) at
    • upload the keys to default keyserver (if any is set) gpg --send-key <key>
    • upload the keys in bunch to a list of keyservers using bash
      for line in $(cat <list-file>); do
      gpg --keyserver $line --send-key <key>;

    my personal list:
  • import the needed striped secret sub-keys into your devices and store the others in a safe, possibily offline and encrypted place. I would also suggest to store them in more than a place, just in case of a disaster. Without the Certification key, we cannot modify them and without the revocation key, revocate compromized ones.


  • subkey does not delete
    it is not possible to delete a key directly with gpg, we need to make use of the gpg-agent this way:
    # Obtain the keygrip of the subkey you want to delete.
    $ gpg --with-keygrip --list-secret-keys "$YOUR_FINGERRINT"
    # Ask gpg-agent to delete the key for you.
    # There should be a graphical confirmation prompt.
    $ gpg-connect-agent "delete_key $KEYGRIP" /bye


  • Key reports back: gpg: agent_genkey failed: No such file or directory in such case, just kill the agent and continue gpgconf --kill gpg-agent

example procedure to modify the keys

  • mount/copy the safe backup with the secret keys somewhere safe, as in point 1 of the manual creation
  • kill the gpg-agent if running gpgconf --kill gpg-agent
  • set the GNUPGHOME variable export GNUPGHOME=/path/to/mount/.gnupg list the secret keys gpg -K
  • enter key editing (--expert for more options) gpg --edit-key
  • export modified keys (see manual section)
  • populate keyservers with modifications (see manual creation for details)
  • populate applications that also make use of the pubkey, like Github and Gitlab.
  • populate keybase with modifications by opening the app and using keybase pgp update

seach keys and store keyserver for fast interrogation

example: gpg --keyserver --search-keys <key>

to abbreviate the input, we can create the file ~/.gnupg/dirmngr.conf and add the keyserver used for checking


might be necessary to run dirmngr at least once and reload the agent if already running with gpgconf --reload dirmgr

then keys can now be searched with gpg --search-key <key> and --search-keys <key>

Signatures on keys

Having our keys signed is very important on the Web Of Trust, people that know us and have good faith in our handling of the private keys, should assign us a reasonably high trust level, sign our pubkey and send it to us, so we can publish the upgraded key.

To sign a key, we need to have the Certification master key loaded, for this… I’d suggest the same procedure as in the manual creation for the creation of a safe environment.

Be aware that is good practive to not publish signed pubkeys but to let the owner publish them.

  • import the key by asking for the updated pubkey

    • be sure to use a secure channel or to encrypt it with the Encryption key of our friend, this can be done by them with gpg --encrypt </path/to/> --recipient <[email protected]> </path/to/> or in one command (untested) gpg -a --export <key> | gpg -se -r <key> > >~/path/to/key>.asc.pgp optimally, the email itself should be used during this process, so we can be totally sure they have access to it (and hopefully, they are not also the impostors)
    • decrypt the received pubkey gpg --decrypt </path/to/key.asc.pgp>
    • import the key `gpg –import
  • import by downloading the key from the keyservers gpg --recv-keys <key> or if using a non-default keyserver gpg --keyserver <address.of.keyserver.ext> --recv-keys <key>

  • enter edit mode for the key gpg --edit-key

    • select the uid if we want to sign a single email or skip to select all uid <n>
    • sign only using sign
    • or sign better using trust levels
      • set the trust on the keyring (not sure, might not be necessary) trust

      • sign with trust (there are other types on the documentation tsign

      • we are prompted twice for the various levels of trust we have in this key, the first one defines how much we are sure about the identity of the key’s owner (2, we are sure about identity, 1 not totally sure), the second defines how much we are willing to go deep with the sign, any value above 1 means that we also trust keys that this person might sign. A key that has 3 marginal (1) signs is considered trusted during verifications if we also have the other 2 keys in our keyring. I highly suggest the D’Artagnan story to fully understand the various trust levels.

        ideally, we should fully verify the identity (2) and assign a marginal level on trust (1) on the keys this person might sign, unless that person is another key of ours, in which case.. We might trust ourself, or not if it is a key dedicated to untrusty things, you know how you are gonna use it.

    • signatures are revokable, unless nrsign or nrtsign is used (non-revokable), which should really only be used with our personal keys or some legaly keys we want to sign because we are departing to afterlife. it can be done with revsign not sure about the implications, tho… but you know that you can, let’s say that person becomes untrusty or they have their keys compromised and are not able to revoke them for whatever reason.
  • see if our signature has been successfully applied gpg --list-signatures <key>

  • export the pubkey and send it to our friend in the same way, by encrypting it and sending it via a certified/secure channel.


  • during sign, this error pops up gpg: no default secret key: No public key it might be because we have a smartcard (Yubikey) inserted, which has keys associated with different key. Just remove it and try again.


initial setup

  • install all the needed packages for reading the key (refer to your distro documentation for this, generally suffice to search and install all packages that have yubi or fido2 in the name, but we might also want to install only those relative to the smartcard operations)
  • change the PIN and Admin PIN default pin is 123456, new PIN must be 6 digits gpg --card-edit passwd default admin pin is 12345678, new PIN must be 8 characters admin passwd
  • assign informations on the card (admin mode) name lang (i.e. en) login (i.e. frayoshi) sex (i.e. M) url (where to retrieve the pub key - i.e.
  • show added informations gpg --card-status

add keys

note: keys are MOVED/linked, export the secret subkeys before hand as backup if you want to reuse it!
note2: exported subkey AFTER the move to the smartcard is DIFFERENT from the one before.
note3: public key file is hash identical with or without the key on the smartcard.

  • enter edit mode gpg --edit-key <key>
  • select the subkey to MOVE/link key <subkey ID>
  • move to the yubi keytocard and then select the one we want to move if multiple options are given.
  • save and quit save
  • export the secret subkey with the stub indicating it is on a smartcard (~>~) and then import this on the main computer’s keyring.
  • import the key and then refresh the main computer’s keyring and tell it to look for the stubs on the card by using gpg --card-status
    • seem like the importing phase is not necessary, as --card-status does create the keygrips.

backup or restore keys

note: there’s a bkuptocard command I have not explored.

links to the keys are stored as keygrip files, which by default are located under $HOME/.gnupg/private-keys-v1.d/ to restore the state from “link to smartcard” (>) to “missing secret-key” (#) we delete the keygrip relative to the key.

  • find the keygrip gpg --with-keygrip -k <key>
  • locate and remove from the directory
  • import the secret subkey (not on the smartcard) gpg --import </path/to/secret-subkey.gpg>
  • repeat the procedure to move the secretkeys to the smartcard.


the gpg stub to the keys will always point to the one we moved it lastly. To force the repointing to the one which is connected now, we can make use of gpg-connect-agent "scd serialno" "learn --force" /bye

NOTE: This will override secret keys we might have locally, which will need repointing and have no gone deeper into the argument.

It is recommended to create an alias for this command.

check integrations for existing app, included gnome-keyring


sent to my acquaintance, The Doctor

more notes

anatomy of a GPG key

keys creation

Sign of keys

Note that “l” (for local / non-exportable), “nr” (for non-revocable, and “t” (for trust) may be freely mixed and prefixed to “sign” to create a signature of any type desired.

revoke signs:

Good argument on RSA vs DSA

Export subkey striped and create a dedicated password for it

semi-complete guide

Generate key from script

Trust levels

D’Artagnan was the captain of the King’s musketeers, reporting directly to his commander, M. De Tréville, who in turn reported directly to King Louis XIII. In the book, the queen-escort Anne d’Autriche and her lover the Duke of Buckingham run the risk of getting exposed due to Cardinal Richelieu’s plotting. In desperation, Anne turns to her trusted courtisane, Constance Bonacieux, asking her to find someone she trusts for a quick trip to England. Cardinal Richelieu finds that out and tasks his henchman, Comte de Rochefort, to make sure the queen’s desperate plot fails.


level 1: “you can trust this key I’ve signed as much as mine, but that’s as far as I’m willing to vouch“ level 2: “you can trust this key I’ve signed as much as mine, plus any other key this person trust-signs, if you are so inclined”

In cryptographic parlance, trust-signing a key with “level 1” designates that person as a “Trusted Introducer.” Trust-signing a key with “level 2” designates that person as a “Meta-introducer”.


GPG card (yubikey)

Safe Creative

Help the author to continue publishing,
donate now or use an affiliate link.

⭐ Click here to choose ✨

You can also become an Affiliate for my content at this Link

  Made with Bulma   build with   Build with Hugo   hosted on the amazing Contabo and Vultr VPS

  © 2019-2021 Francesco Yoshi Gobbo - PGP 3FC5F028E7AFF594 - ISNI 0000000502954809 - P.IVA / VAT: IT-01572520052

privacy policy | cookie policy