Skip to content

Instantly share code, notes, and snippets.

@karakays
Last active July 12, 2022 07:56
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save karakays/e2c95f532a9d09756e0dccf554bf6fbc to your computer and use it in GitHub Desktop.
Save karakays/e2c95f532a9d09756e0dccf554bf6fbc to your computer and use it in GitHub Desktop.

GNU Privacy Guard

GPG keychain

master key and subkeys

Key identities

key id vs key fingerprint why key is identified by last 8 digits of its finger print (and not first for instance?)

Use cases

List all public keys

❯ gpg --list-keys --list-options show-unusable-subkey

List all secret keys

❯ gpg --list-secret-keys --list-options show-unusable-subkey

renew expired keys

❯ gpg --edit-key $KEYID
gpg> key 1
gpg> expire
gpg> save

remove private master key from keyring

❯ gpg --list-secret-keys --with-keygrip
❯ gpg-connect-agent "DELETE_KEY <master-grip>" /bye

export secret keys only to port

❯ gpg --export-secret-keys --armor --output <out>

export secret subkeys only to port

❯ gpg --export-secret-subkeys --armor --output <out>

import secret keys from file

❯ rm -rf .gnupg/private-keys-v1.d
❯ gpg --import file
❯ gpg-connect-agent reloadagent /bye

publish local changes to keyserver

❯ gpg --keyserver pgp.mit.edu --send-keys $KEYID

update from keyserver

❯ gpg --refresh-keys

kill gpg-agent

❯ gpgconf --kill gpg-agent

SSH-GPG bridge

Export GPG public key in OpenSSH public key format. This selects the key with authentication capability (A flag) from keychain and translates it.

❯ gpg --export-ssh-key

Translate any kind of GPG key (any capability, revoked, expired etc.) to SSH key with monkeysphere framework.

❯ gpg --export-key | openpgp2ssh $KEYID

Take a caveat that openpgp2ssh cannot handle password-protected keys. Such keys must remove password removed first ref

Authentication agents

ssh-agent

An authentication agent which holds private keys for PKI authentication. Initially, it doesn't hold any key. Keys are added to the agent via ssh-add. The idea is running in goodprivacy.mdlocal machine (terminal) and to keep authentication data in memory so it doesn't need to be stored anywhere in runtime. Private key operations are only done by the agent. SSH talks to the agent over SSH_AUTH_SOCK domain socket and private is never sent to the ssh.

Start ssh-agent

eval `ssh-agent -s`

Add private key file to the agent

ssh-add [file ...]

If no args given, add the default keys ~/.ssh/{id_rsa,id_dsa,id_ecdsa)

ssh-add
# list public keys of identites currently hold by agent
ssh-add -L

gpg-agent

A daemon to manage GPG private keys. It is used as a backend to gpg and some other utilities in a protocol-transparent manner.

gpg-connect-agent

gpg-connect-agent is the client to send protocol-specific commands to gpg-agent server.

gpg-connect-agent --[gpg-agent-protocol]--> gpg-agent

gpg-connect-agent "/echo hey this is gpg-connect command echo"

Restart gpg-agent

gpg-connect-agent reloagent /bye

Kill gpg-agent

gpg-connect-agent killagent /bye

tty command prints tty device (terminal) for the current interactive shell. GPG_TTY environment variable holds active terminal name for GPG.

gpg-agent with ssh-support

If enable-ssh-support option is set, gpg-agent both supports its own gpg-agent protocol and ssh-agent protocols so both gpg and ssh clients can communicate to the same agent. In a typical flow, ssh client prepares a signature request and sends it to the agent over the ssh-agent protocol. How ssh command finds the agent address is specified in the SSH_AUTH_SOCK variable. By settings this to the gpg-agent location, we are telling ssh to talk to gpg-agent for signature requests.

In case the key is password protected, gpg-agent needs to prompt the user for the passphrase to decrypt the key. If gpg-agent gets commands in ssh-agent protocol and there are multiple terminals (for example as in tmux), gpg might ask for passphrase in an unrelated terminal display. This is because ssh-agent protocol has no way to convey currently active terminal information, the protocol simply doesn't support that. So gpg-agent has no clue in what terminal to prompt the user for the passphrase and as a result it always assumes the TTY where it has been started and shows the password input there. To switch the display to current one

gpg-connect-agent updatestartuptty /bye

However, initially, SSH keys still need to be added to the agent through ssh-add. This is a manual process but as an alternative way, keygrips can be specified in ~/.gnupg/sshcontrol and gpg-agent loads them automatically.

gpg-agent holds private keys in .gnupg/private-keys-v1.d. Each key is stored in a separate file with a name of keygrip. If one the keys are removed from there, thay key is shown as offline with # in the gpg --list-secret-keys output meaning private key is missing and not usable.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment