NOTE: if you’re on Windows, you should install Gpg4win. git-bash may also provide the gpg utility.
What is GPG
GPG (GnuPG) or GNU Privacy Guard is a versatile key management system allowing you to encrypt and sign data and communications.
Checking version
$ gpg --version
gpg (GnuPG) 2.2.41
libgcrypt 1.10.2-unknown
Copyright (C) 2022 g10 Code GmbH
License GNU GPL-3.0-or-later <https://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Home: /home/minno/.gnupg
Supported algorithms:
Pubkey: RSA, ELG, DSA, ECDH, ECDSA, EDDSA
Cipher: IDEA, 3DES, CAST5, BLOWFISH, AES, AES192, AES256, TWOFISH,
CAMELLIA128, CAMELLIA192, CAMELLIA256
Hash: SHA1, RIPEMD160, SHA256, SHA384, SHA512, SHA224
Compression: Uncompressed, ZIP, ZLIB, BZIP2
Generating a key
To generate a default key you can use gpg --gen-key
, to get more options you can use gpg --full-generate-key
.
For a guide on the first command see here.
Lets generate a key:
$ gpg --full-generate-key
The first option is to pick the type of key, for this I am going to go with the default RSA and RSA
(1), you can pick whichever based off preference and use case.
gpg (GnuPG) 2.2.40; Copyright (C) 2022 g10 Code GmbH
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Please select what kind of key you want:
(1) RSA and RSA (default)
(2) DSA and Elgamal
(3) DSA (sign only)
(4) RSA (sign only)
(14) Existing key from card
Your selection? 1
Next we need to choose how many bits we want, personally I like to pick something 3072 or more, but you can read more about large RSA keys here.
For this key, I’m going to stick again with the default of 3072.
RSA keys may be between 1024 and 4096 bits long.
What keysize do you want? (3072) 3072
Once we’ve chosen a key and bit length, we need to choose when it should expire. It is good practice to have keys expire every few years (though frequent expirey doesn’t mean security). For personal use I like to make my keys expire every 2 years, so for this key I’m going to choose that.
Requested keysize is 3072 bits
Please specify how long the key should be valid.
0 = key does not expire
<n> = key expires in n days
<n>w = key expires in n weeks
<n>m = key expires in n months
<n>y = key expires in n years
Key is valid for? (0) 2y
We then need to associate a name with the key, pick a name you’re good with, ideally something used to identify you or whoever is going to be using the key. I’m going to set the name for this to be hello world
.
Key expires at Tue 20 May 2025 08:45:54 PM EDT
Is this correct? (y/N) y
GnuPG needs to construct a user ID to identify your key.
Real name: hello world
You will then be prompted to enter an email address, this is optional, so I am going to leave it blank.
Email address:
Next you get the option to add a comment, put something here to help you remember what the key is for. This is optional.
Comment: This is a test key
Once you’ve finished you will get the option to edit these fields in case you made a mistake, I’m happy with this key so I’m going to choose okay.
You selected this USER-ID:
"hello world (This is a test key)"
Change (N)ame, (C)omment, (E)mail or (O)kay/(Q)uit? O
The last step (optional), is to enter a passphrase, you will likely get a dialog or prompt in your terminal to enter it, here’s what mine looks like:
You should protect your key with a passphrase to ensure that it cannot be used by anyone who doesn’t know the passphrase. Ideally this would be strong enough to resist brute force for enough to time revoke the key, or even better forever.
Once you’ve set a passphrase, you will see an output like this:
We need to generate a lot of random bytes. It is a good idea to perform
some other action (type on the keyboard, move the mouse, utilize the
disks) during the prime generation; this gives the random number
generator a better chance to gain enough entropy.
We need to generate a lot of random bytes. It is a good idea to perform
some other action (type on the keyboard, move the mouse, utilize the
disks) during the prime generation; this gives the random number
generator a better chance to gain enough entropy.
gpg: revocation certificate stored as '/home/minno/.gnupg/openpgp-revocs.d/B44FA5959352450581BAE339E135DD909794B108.rev'
public and secret key created and signed.
pub rsa3072 2023-05-22 [SC] [expires: 2025-05-21]
B44FA5959352450581BAE339E135DD909794B108
uid hello world (This is a test key)
sub rsa3072 2023-05-22 [E] [expires: 2025-05-21]
This is your new GPG key, your key can be identified via the fingerprint
, which is the long string show above the uid
, mine for this key is B44FA5959352450581BAE339E135DD909794B108
Quick usage
Listing keys
To see public keys you have:
$ gpg --list-keys
To see private keys you have:
$ gpg --list-secret-keys
Exporting keys
To export the a public key:
$ gpg --output "some-file-path.gpg" --armor --export "fingerprint / user-id"
To export a private key:
$ gpg --output "some-file-path.asc" --armor --export-secret-keys "fingerprint / user-id"
-
--output
or-o
is used to specify the output file for the key, or if not specified it puts it into stdout. -
--armor
wraps the key into ASCII instead of binary format. -
--export
is determines which public key to export, wherefingerprint / user-id
is either the fingerprint of the key you want to export, or the name / email on that key. -
--export-secret-keys
is determines which private key to export, wherefingerprint / user-id
is either the fingerprint of the key you want to export, or the name / email on that key.
NOTE: order matters here, --export
and --export-secret-keys
should usually be last
Importing keys
To import a public or private key:
$ gpg --import "some-file-path.gpg"
Signing / trusting keys
Once you have imported someones public key, signing that key will tell your software you trust and have verified that it is associated with the person in question.
To sign a key you’ve imported:
$ gpg --sign-key "fingerprint / user-id"
If you have multiple private keys, you can specify which key to sign with using --default-key
and the fingerprint or user-id.
Once you’ve signed their key, you can export it and send it back to them. This lets them import the key to gain a “stamp of approval” when interacting with others.
Encrypting data
Once you have someones public key, you can use it to encrypt a message for them.
This can be done like so:
$ gpg --encrypt --sign --armor --recipient "name" "path-to-file"
-
--encrypt
encrypts the file with the recipient’s public key. -
--sign
(optionally) signs the file with your private key. -
--armor
wraps the data in ASCII instead of binary format. -
--recipient
or-r
specifies the public key using it’s name -
lastly the path to the file you want to encrypt / sign
If you have multiple private keys, you can specify which key to sign with using --default-key
and the fingerprint or user-id.
Signing data
To sign a piece of data with your private key:
$ gpg --sign "path-to-file"
If you want to make a message readable, but still sign it with your private key, you can use --clearsign
.
$ gpg --clearsign "path-to-file"
This will output something like:
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA256
hello world
-----BEGIN PGP SIGNATURE-----
iQJeBAEBCABIFiEE5oWKLvg0/hlBE+xWteUE4eykbTIFAmRrAT0qHDYyNDUxNDE1
K21pbm5vd29AdXNlcnMubm9yZXBseS5naXRodWIuY29tAAoJELXlBOHspG0yhwMQ
AMg8TRGB0Q18vQy0DDbla7CDC53mtP5uUP341+o3QWbCujyw+cR+N3zo0C3txz4B
69yV34U48RaQdeIO+uF1cL0kCmTE4AVDPpIeqdVH/IeWsgi5cpy2ZdAFXON4bheC
EU7yfBdPfX1J5Ton+I3AVW2ChzCKhifPrw3KuKKDcOZRLn06F3tgigWjV9DAq8Bm
Apqnc7oFY55Wg7wPjI36sitGvxfbMGcy3z6D2PlwJjFkRWEHjkP3jaCqv5ptiI4b
PjjuR+vpE7e+UnQWP2NtOAGFBSkz2rItU6vVtqyFKa9TEgrmRbaFqEUbwVPpUR32
kTBgI2r+FHxdUeZpc2IDCwbkhnqnC5fJsIhJkiwoYBgtEDOSkS5Y73QYufsO2o7J
9qph8MLGq4LNseIbrcB+U7aCcg4lSkolPXpHpHrWPWehG5nzwzXy3dm4zJ/wUaUx
7akeCKV8Yom+Q3IeKREBw13bgDUGot9pSz0WD79WTQL9gjY/WlH1k3xAs3JA5fVK
MS4ddHX5qBiqt+LrE506MoN0Bjvuct7DvNy87e/68iU9mC8kK+95zIqASoa8qSWO
5MZ2JQxpIrT6KJcDBE7XQWvknKDbmi8lX94Upbhu9WeFv15aUf13/+CXXjHlBF2m
0XvhzxQlVgpqk0evlTviMjOqqCe4tUk0w/rWDWHBhiCv
=1IjM
-----END PGP SIGNATURE-----
Verifying signed data
You can decrypt / verify using:
$ gpg "path-to-file"
If you do not have the public key of the signer, you will get something like:
gpg: WARNING: no command supplied. Trying to guess what you mean ...
gpg: Signature made Mon 22 May 2023 01:54:11 AM EDT
gpg: using RSA key E6858A2EF834FE194113EC56B5E504E1ECA46D32
gpg: issuer "62451415+minnowo@users.noreply.github.com"
gpg: Can't check signature: No public key
If you have the public key, but did not trust it, you will get something like:
gpg: WARNING: no command supplied. Trying to guess what you mean ...
gpg: Signature made Mon 22 May 2023 01:54:11 AM EDT
gpg: using RSA key E6858A2EF834FE194113EC56B5E504E1ECA46D32
gpg: issuer "62451415+minnowo@users.noreply.github.com"
gpg: Good signature from "Minnowo (Alice Nyaa) Github <62451415+Minnowo@users.noreply.github.com>" [unknown]
gpg: WARNING: This key is not certified with a trusted signature!
gpg: There is no indication that the signature belongs to the owner.
Primary key fingerprint: E685 8A2E F834 FE19 4113 EC56 B5E5 04E1 ECA4 6D32
If you have the public key and trust it, you will get something like:
gpg: WARNING: no command supplied. Trying to guess what you mean ...
gpg: Signature made Mon 22 May 2023 01:54:11 AM EDT
gpg: using RSA key E6858A2EF834FE194113EC56B5E504E1ECA46D32
gpg: issuer "62451415+minnowo@users.noreply.github.com"
gpg: Good signature from "Minnowo (Alice Nyaa) Github <62451415+Minnowo@users.noreply.github.com>" [full]
You can use --output
or -o
to specify the output file of any encrypted / signed data.
NOTE: the input file should be specified last after any parameters you provid