master key and subkeys
key id vs key fingerprint why key is identified by last 8 digits of its finger print (and not first for instance?)
❯ gpg --list-keys --list-options show-unusable-subkey
❯ gpg --list-secret-keys --list-options show-unusable-subkey
❯ gpg --edit-key $KEYID
gpg> key 1
gpg> expire
gpg> save
❯ gpg --list-secret-keys --with-keygrip
❯ gpg-connect-agent "DELETE_KEY <master-grip>" /bye
❯ gpg --export-secret-keys --armor --output <out>
❯ gpg --export-secret-subkeys --armor --output <out>
❯ rm -rf .gnupg/private-keys-v1.d
❯ gpg --import file
❯ gpg-connect-agent reloadagent /bye
❯ gpg --keyserver pgp.mit.edu --send-keys $KEYID
❯ gpg --refresh-keys
❯ gpgconf --kill gpg-agent
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
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
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
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.
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.