PGP Guide
Encryption is a method which makes information hidden, so that it can't be decrypted (i.e., unencrypted) without special knowledge, such as a password or a key. Alongside encryption, a digital signature is a scheme demonstrating the authenticity of digital information; a valid signature gives the recipient reason to believe that data was created by the known sender, and that it wasn't altered in transit. Various encryption standards, algorithms, and protocols are available for use depending on the need; SSL, SSH, HTTPS, IPsec, etc.
Here, OpenPGP (or "Pretty Good Privacy") is one of those standards of encryption which can be used to encrypt and sign data. There are many implementations for OpenPGP, most important of which is GnuPG (or "GNU Privacy Guard").
GnuPG encrypts data using asymmetric key pairs, individually generated by GnuPG users; the "public key" and "private key":
- The public key is used by the sender(s) to encrypt data.
- The private key is used by the recipient to decrypt data.
Similarly, it can also be used to sign data in order to avoid forgery or tampering:
- The private key is used by the sender to sign data.
- The public key is used by the recipient(s) to verify the data's authenticity.
Installing GnuPG ~
There exist many graphical front-ends to GnuPG, but they don't concern this guide since they're self-explanatory, and their usage differ from front-end to another. What really matters is that GnuPG itself comes with a command-line interface provided in Linux (and BSD) operating systems, which allows us to understand how the entire thing works.
To install GnuPG, you need to get it from your distribution's package manager. For example, to get it from the Arch Linux repositories, issue the command: pacman -S gnupg
. This will install GnuPG (with the version being at least "2.0.0"). You can check the version by issuing: gpg --version
.
Generating Keys ~
To create a private and public key pair, issue the command: gpg --full-generate-key
. This will bring up a selection screen with many options in GnuPG:
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) > Your selection? 1 RSA keys may be between 1024 and 4096 bits long. > What keysize do you want? 4096 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 > Is this correct? (y/N) y
In this example, we used the sensible defaults that every key pair generation should use:
RSA and RSA
for the key would enable both encryption and signing.4096
for the keysize would use the most secure size against brute-force attacks (will take a significant generation time).0
for the expiration date would make it exist for as long as Allah wills. You can change this according to your needs.
You can also issue gpg --full-generate-key --expert
to reveal all expert GnuPG options, so (for example) if you want a weird elliptic curve instead of a large prime number for your key generation algorithm, you can choose ECC and ECC
(with the Curve 25519
curve) instead of RSA and RSA
(with the 4096
keysize). It has the same extreme encryption security, as far as I know.
Afterwards, GnuPG would ask for some user data (i.e., a name, an email address, and a comment) which is only used for making encryption and decryption easier, but they can be completely fake if you want to. The comment should remain blank since it just adds to the confusion (who even needs that anyway?):
GnuPG needs to construct a user ID to identify your key. > Real name: Hatsune Miku > Email address: miku@dayo.jp > Comment: You selected this USER-ID: "Hatsune Miku <miku@dayo.jp>" > Change (N)ame, (C)omment, (E)mail or (O)kay/(Q)uit? o
Next, it'll ask for a passphrase to be used for doing sensitive things with your private key (e.g., signing, decrypting, and exporting the private key itself); this is merely a protective security layer, so if someone with physical access to your computer wants to steal your private key, they will need the passphrase. Make sure to use a good password! You definitely don't want your private key in the wrong hands.
Finally, you'll be asked to (optionally) type on the keyboard (or hover with your mouse, utilize the disks, etc.) in order for randomization to take place while the key pair is being generated. This is done so that the encryption algorithm has more human-entered elements, which (combined with the passphrase entered above) will result in the user's private key.
That's it, the key pair generation was a success!
pub rsa4096 2007-08-31 [fingerprint] uid Hatsune Miku <miku@dayo.jp> sub rsa4096 2007-08-31
You can afterwards edit ~/.gnupg/gpg.conf
(or $XDG_DATA_HOME/gnupg/gpg.conf
, depends where you set up your GnuPG directory) and set the new secret key as the default key using the fingerprint of the key pair:
default-key [fingerprint]
The Private Key ~
Listing Private Keys ~
Simply issue: gpg --list-secret-keys
. The private key is called a "secret key" in GnuPG merely for historical reasons.
Exporting the Private Key ~
Preventing the need to create a new key pair (in case your hard drive fails or something), you should export your private key and keep it safe somewhere (e.g., storing it on a USB, syncing it across multiple devices, keeping it in its own Git repository, etc.).
To export the private key, issue: gpg --armor --export-secret-keys [name/email/id] > private-miku.asc
. You can also encrypt the output using a password (it could be the same as your private key's passphrase) for extra security; you can read about doing that below in Symmetrical Encryption.
Oh, and let's talk about --armor
before we continue; by default, keys (as well as any other output from GnuPG such as encrypted data, signatures, etc.) are exported in a binary format. Key pairs in binary format are inconvenient when dealing with key pair exchange, so therefore, GnuPG supports a command-line option called --armor
that causes the output to be generated in an ASCII-armored format instead of a binary format.
Importing the Private Key
Simply issue: gpg --import private-miku.asc
.
The Public Key ~
Listing Public Keys ~
Simply issue: gpg --list-public-keys
or simply: --list-keys
.
Viewing Information of Public Keys ~
If you want to view the full information about your (or any other) public key, just issue: gpg --list-keys --with-fingerprint --keyid-format=[short/long] [name/email/id]
. The result would be something like this:
pub rsa4096/[id] 2007-08-31 Key fingerprint = [fingerprint] uid Hatsune Miku <miku@dayo.jp> sub rsa4096/[subkey] 2007-08-31
The output's layout might change depending on the version used, but it's always self-explanatory:
[fingerprint]
is the key's fingerprint (a unique hexadecimal number). It can be used instead of the ID.[id]
is an ID that you can use to easily identify your key (which is the last part of the key's fingerprint; the[short]
option gives off its last 8 digits, and[long]
gives off the last 16 digits).[subkey]
is the subkey (irrelevant).
Exporting the Public Key ~
For people to encrypt data that only you can decrypt, you must exchange public keys. To send your public key to a correspondent, you must first export it by issuing something like: gpg --armor --export [name/email/id] > public-miku.asc
, which outputs the .asc
file into the current directory so you can send it to others and have them import it.
Importing Public Keys ~
In order to encrypt data to someone else using their public key, you first need to import it by issuing: gpg --import public-teto.asc
.
Signing Public Keys ~
It's very important to validate the person from whom you receive a public key; you can't just download the public key of someone you know and trust it as his public key since it could be someone else's. Therefore, after checking the public key's fingerprint and associated information, you can import it (as seen above) and sign it by issuing: gpg --sign-key [name/email/id]
, and add it to your trust database by issuing: gpg --edit-key [name/email/id]
and typing trust
.
When you sign someone's public key you are effectively saying: "I testify that this key actually belongs to this person." People who trust you and your judgement can verify the signature of that public key.
Verifying Public Key Signatures ~
To verify a public key that is signed by someone you know, you need to import the key then verify if someone you know has signed it with: gpg --check-sigs [name/email/id]
, so you can sign it and trust it afterwards (thus building a "Web of Trust").
Note that sometimes when using --check-sigs
, something similar to this may appear:
<n> signatures not checked due to missing keys.
That just means that the key you received has also been signed by other people, but since you don't have their public keys, you can't verify their signatures.
Editing Public Keys ~
Simply issue: gpg --edit-key [name/email/id]
then type help
for a list of commands. For example; check
to check the signatures added to the public key, clean
to clean unusable user IDs and signatures, quit
to quit, etc.
If you edit your own key you will get so many more options, like changing the password of your private key (with passwd
) or even setting "a photo" on your public key! This will obviously make the public key much larger in size, though...
Deleting Public Keys ~
To delete an imported public key for whatever reason (such as if a user generated a new key pair and you need to delete their old public key before importing the new one), you need to issue: gpg --delete-keys [name/email/id]
.
Encrypting Files ~
To encrypt a file with a user's public key, you need to issue: gpg --encrypt --recipient [name/email/id] file.txt
. The command will result in the creation of a file called file.txt.gpg
which is in a binary format.
If you would like it to be an ASCII-armored version instead, simply add --armor
to the command so it looks like this: gpg --armor --encrypt --recipient [name/email/id] file.txt
.
Symmetrical Encryption ~
Symmetric cryptography uses a secret, shared password for encrypting data, rather than a public key to encrypt and a private key to decrypt. GnuPG allows doing that too with the --symmetric
option: gpg --symmetric --armor --cipher-algo AES256
.
Here, we used --cipher-algo AES256
since AES256
is the most secure algorithm.
Decrypting Files ~
To decrypt a file encrypted with your public key (or with a shared password), you need to issue: gpg --decrypt file.txt.gpg
or simply: gpg file.txt.gpg
.
If the file was signed (as seen above), something like this would appear on the command-line as well:
gpg: Good signature from "Kasane Teto <teto@pote.to>" Primary key fingerprint: [fingerprint]
Signing Files ~
To sign files (so that can we be sure that the person who sent the file is actually who they claim to be), simply issue: gpg --sign file.txt
. You can use this along with encryption (since signing and encrypting is a lovely couple) and also use --armor
to wrap the file in an ASCII-armored signature.
If you, however, only want to generate a signature for a file without encryption, then you'll need to issue: gpg --detach-sign file.txt
, which will result in file.txt.sig
that only contains your signature of that file (without the file itself). The signature is in binary format, so you might also want to use --armor
or simply issue: gpg --clearsign file.txt
to wrap the the signature in an ASCII armor (which results in a .asc
file rather than .sig
).
Verifying Signatures ~
To verify a file's signature (without outputting the data), issue: gpg --verify file.txt.gpg
. In the other hand, to verify a detached signature (whether .sig
or .asc
), issue the command: gpg --verify file.txt.sig
. Same command, same assignment; only verification.
Abbreviations ~
Annoyed of writing long commands? Fortunately, there exist many abbreviations for common options which I'll list here:
Long | Short |
--armor |
-a |
--decrypt |
-d |
--detach-sign |
-b |
--encrypt |
-e |
--list-public-keys or --list-keys |
-k |
--list-secret-keys |
-K |
--recipient |
-r |
--sign |
-s |
--symmetric |
-c |