Skip to content

Instantly share code, notes, and snippets.

@felipeasimos
Last active May 2, 2023 13:15
Show Gist options
  • Save felipeasimos/11b4c8ec34e2fa8cea8f1dc88f72684b to your computer and use it in GitHub Desktop.
Save felipeasimos/11b4c8ec34e2fa8cea8f1dc88f72684b to your computer and use it in GitHub Desktop.
# GPG
sources: https://egel.github.io/2020/08/10/create-the-revocation-certificate-for-you-gpg-key.html \
https://www.devdungeon.com/content/gpg-tutorial \
https://ryanlue.com/posts/2017-06-29-gpg-for-ssh-auth \
https://oguya.ch/posts/2016-04-01-gpg-subkeys/ \
https://opensource.com/article/19/4/gpg-subkeys-ssh-multiples \
https://gist.github.com/fijimunkii/54089bce9af6a68fd75536496cba6030 \
https://unix.stackexchange.com/questions/31996/how-are-the-gpg-usage-flags-defined-in-the-key-details-listing \
https://www.saminiir.com/establish-cryptographic-identity-using-gnupg/
GNU Protection Guard's openPGP encryption. It stores keys in a local
keyring. To use a key, it must be in the local keyring.
## List Keys
You can see your public keys with `gpg --list-keys` and your
private key with `gpg --list-secret-keys`.
## Create Keys
`gpg --gen-key` will walk you through an interactive prompt to aid
you in creating a new key pair.
## Delete Key
`gpg --delete-secret-keys <key uid>`, deletes private keys, and
`gpg --delete-keys <key uid>`, deletes public keys.
## Export Key
You can see a key with `--export <key uid>`, for public keys, and
`--export-secret-key <key uid>`, for private keys.
You may want to redirect the output to a file:
```
gpg --export <key id> > a
```
You can also use `--armor` to show the key in a readable format:
```
gpg --export <key id> --armor > a
```
## Import Key
You can import a key from a file. The syntax for public and
private keys is the same:
```
gpg --import ./filename
```
You can also import from a server:
```
gpg --keyserver pgp.mit.edu --recv <key id>
```
## Crytographic Operations
### Encryption
You can either encrypt symmetrically (usually using AES)
or asymmetrically (usually using RSA).
In both cases you can add:
* `--armor` - for a readable output
* `--sign` - to also sign the output
* `--output` - to specify output file
#### Symetrically
```
gpg --symmetric <filename>
```
Will prompt you for a passphrase.
#### Asymmetrically
```
gpg --encrypt <filename>
```
Will prompt you for a passphrase.
### Decription
With `gpg --decrypt <filename>` or `gpg -d <filename>`
you can decrypt a file. `gpg` will automatically:
* verify signature if there is one.
* detect if it is symmetric or asymmetric.
* use the appropriate private key if available.
* automatically prompt for a passphrase if the file is
symmetrically encrypted.
### Signatures
You can sign files that were symmetrically or asymmetrically
encrypted. This can be used to prove that you confirmed the
contents of the file at the time of your signature. This
is optional.
#### Clear Signature
```
gpg --clearsign <filename>
```
Will output the file with no signature.
#### Signing
```
gpg --sign <filename>
```
#### Verify Signatures
When you decrypt signed files, their signatures will be
automatically verified. You can also check without decrypting
them:
```
gpg --verify <filename>
```
However, sometimes you may get the signature file
separatedly. They usually come in `.asc`, which can
be used to confirm the contents of an encrypted file:
```
gpg --verify <signature> <filename>
```
You can also detach the signature from the encrypted
file, if it comes embedded:
```
gpg --detach-sign <filename>
```
This will output `<filename>.sig`.
### KeyServers
You can publish your public key to keyservers.
#### Publish Key
```
gpg --send-keys --keyserver <keyserver> <key-id>
```
#### Revoke Key
How to remove a key you published to a server? You need a
revocation certificate for that key to make it happen. Do this
only if the keys have been compromised.
```
gpg --output revoke.asc --gen-revoke <key-id>
```
When you want to revoke the key, import the revocation certificate:
```
gpg --import revoke.asc
```
To revoke keyserver keys, just do the same you would do to update the
key:
```
gpg --keyserver <keyserver> --send-keys <keyid>
```
### Subkeys
You can have subkeys related to a master key. This can be useful since
a subkey being compromised won't affect all the other ones, and
they can be individually revoked without compromising the whole keychain.
Subkeys can have specific capabilities: authentication, signing or
encryption. When a regular GPG is created, it actually has a signing
subkey and an encryption subkey.
These capabilities are represented by characters:
| S | C | E | A |
|---|---|---|---|
| signing | certification | encryption | authentication
#### Keygrip
While only keys have IDs, all subkeys have keygrips. They can be
seen by using:
```
gpg -K --with-keygrip
```
#### Generate New Subkey
To generate a subkey, we enter the `gpg --edit-key <keyid>` prompt and use the
`addkey` command:
```
gpg> addkey
```
This will prompt for some information, like it is done when we create
a regular gpg key.
To create a subkey with specific capabilities, use the `--expert` option:
```
gpg --expert --edit-key <keyid>
```
More prompts will appear than usual, one of them even asking about the
capabilities.
#### Add new Subkey
We will use a local keystore that we will delete later, since if we
impor the key and then add it to the keychain, we would have to keep
the separate key in the store forever.
This is how we import a key with ID `<subkey-id>` from a file
`<subkey-file>` to a keychain with ID `<keychain-id>`:
1. Create a temporary keystore.
```
mkdir temp_gpg/
```
2. Import our keychain from the original keystore to the temporary.
```
gpg --export-secret-keys <keychain-id> | gpg --import --homedir temp_gpg/
```
You can check if it worked with `gpg -K --homedir temp_gpg`.
3. Import the subkey file to the temporary keystore.
```
gpg --homedir temp_gpg/ --import <subkey-file>
```
4. Get the keygrip from the subkey in the temporary keystore.
```
gpg -K --homedir temp_gpg/ --with-keygrip
```
5. Use keygrip obtained and `addkey` to add the subkey to the
keychain inside the `gpg` prompt, when using the `--expert` option
to be able to choose the `Existing key` option.
```
gpg --homedir temp_gpg/ --expert --edit-key <keychain-id>
```
6. Now the keychain is complete! Export it from the temporary keystore
and import it into the main one.
```
gpg --homedir temp_gpg/ --export-secret-key <keychain-id> | gpg --import
```
7. Delete the temporary keystore.
```
rm -rf temp_gpg/
```
You can then delete the key you imported.
#### Authentication
Besides encryption and decryption, gpg can be used for authentication.
By default, an encryption and signing subkeys are created, so let's create
an authentication one.
##### Integrating SSH with GPG
The main thing to enable this to is substitute `ssh-agent` for
`gpg-agent`. To do so, edit these two files:
* `~/.gnupg/gpg-agent.conf` - enable ssh support.
```
enable-ssh-support
```
* `~/.bash_profile` - set to launch `gpg-agent` with ssh capabilities on login.
```
export SSH_AUTH_SOCK=$(gpgconf --list-dirs agent-ssh-socket)
gpgconf --launch gpg-agent
```
To make the changes take effect immedietly, kill the `gpg-agent` and run
`~/.bash_profile`:
```
gpgconf --kill gpg-agent
source ~/.bash_profile
```
We must get our ssh key and convert it to a subkey. To do so, we will need
to transform it from the PEM format to a openpgp format. If your ssh key
has `OPENSSH` written on it, it means it was generated by a more recent version
of `openssh`, which means you need to run `ssh-keygen -p -m PEM -f <private-key-file>`,
this command will prompt for a new password, but you can just use the previous one.
To convert from the PEM format to opengpg, use the `pem2openpgp` command, from the
`monkeysphere` package, to convert the ssh key:
```
pem2openpgp <identifier> < <private-ssh-key> > <converted-ssh-key>
```
`<identifier>` will be the ID of the key when we import it.
From now on, you can follow the steps for adding a subkey from a file.
To point to `gpg` which subkey should be used for authentication when using `ssh`,
do:
```
echo <keygrip> > ~/.gnupg/sshcontrol
```
At any time you can use `gpg --export-ssh-key <ID>` to export your SSH key
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment