GPG: The GNU Privacy Guard

We talked about Cryptography Theory before, now let's put that in practice and see some widely used cryptography tool.

GPG, GNU Privacy Guard, is an open source tool allows you to encrypt and sign your data and communications. To recap, encrypt is to ensure confidentiality, and sign is to ensure integrity and nonrepudiation.

Create key pair and share the public key

Create a key pair

$ gpg --gen-key gpg (GnuPG) 1.4.16; Copyright (C) 2013 Free Software Foundation, Inc. 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) Your selection? 1 RSA keys may be between 1024 and 4096 bits long. What keysize do you want? (2048) Requested keysize is 2048 bits Please specify how long the key should be valid. 0 = key does not expire = key expires in n days w = key expires in n weeks m = key expires in n months y = key expires in n years Key is valid for? (0) 1m Key expires at Fri 04 May 2018 08:30:15 AM AEST Is this correct? (y/N) y You need a user ID to identify your key; the software constructs the user ID from the Real Name, Comment and Email Address in this form: "Heinrich Heine (Der Dichter) " Real name: nk Name must be at least 5 characters long Real name: nkkkkk Email address: nk@email.com Comment: You selected this USER-ID: "nkkkkk " Change (N)ame, (C)omment, (E)mail or (O)kay/(Q)uit? O You need a Passphrase to protect your secret key. gpg: key E9F66E1F marked as ultimately trusted public and secret key created and signed. gpg: checking the trustdb gpg: 3 marginal(s) needed, 1 complete(s) needed, PGP trust model gpg: depth: 0 valid: 2 signed: 0 trust: 0-, 0q, 0n, 0m, 0f, 2u gpg: next trustdb check due at 2018-05-03 pub 2048R/E9F66E1F 2018-04-03 [expires: 2018-05-03] Key fingerprint = FC55 55E3 7C49 FE30 1A5D E8E9 D9EC 1FB5 E9F6 6E1F uid nkkkkk sub 2048R/D8CB679E 2018-04-03 [expires: 2018-05-03]

Fingerprints, KeyId, User ID

Some of the gpg commands expect keyId and some expect user id.
Fingerprints is used to uniquely identify a key pair; keyId is the last 8 or 16 characters of the fingerprints, and are called short keyId and long keyId respectively. For example, in the key pair we just created,FC55 55E3 7C49 FE30 1A5D E8E9 D9EC 1FB5 E9F6 6E1F is the fingerprint, and E9F66E1F is a (short) keyId. When the gpg command expects key Id, both fingerprints and short/long keyId can be used. For technical details, check here for the rfc spec
User Id takes the format of "Real Name (Comment) ", you can use part of the User Id as the User Id. When the gpg command expects USER Id, you can use both USER ID and key ID.

Say, --export expects User ID, all the following are valid:
$ gpg --output public.key --armor --export nk@email.com $ gpg --output public.key --armor --export nkkkkk $ gpg --output public.key --armor --export E9F66E1F
To make things easier to remember, key fingerprints always works.

Export your public key

You will need to share your public key with others so that they can 1) encrypt the message for you 2) verify the message if from you.

Unlike ssh-keygen, you will export your public key explicitly. The output is an ASCII version of your public key and you can share it through email.
gpg --output public.key --armor --export user-id

Import your public Key

Once the others get your public key, they will need to import your key. Again, to repeat, so that they can use it to encrypt the message for you, or to verify the message is from you.

Encrypt & Decrypt

There are two user cases for Encryption, 1) you want to encrypt the message so no others can read, 2) you want others encrypt the message so that only you can read it.

In either case, the message will be encrypted with your public key and decrypt with the private key. You already have both keys so no extra steps needed regarding key; For the second case, the user first needs to import your key, and we have discussed how to do that.

Let's say Lily have a doc with some confidential content that she wants to share with me.
$ cat doc This is a confidential doc
To encrypt:
$gpg --recipient user-id --encrypt doc
It will generate an encrypted file called doc.gpg. If you dump it, it looks like this, which is great.
$ cat doc.gpg � ���^\-<��]� WCG� ��O�� t��� L,���X�K9� �O�D������œ� ��� 1L[�o �e-�7p���悌 " �B YKoc�� 5����ػ/ �mQ��;��'� ~5_�tN։�)X+� UC�S� �V ����h�n���?̬ ib8wrp����>�\˼��4Qs���K�ft��a8=���'~C.�\%妌.{�G��DJ��#?sc
After receiving it, you will decrypt it using your private key, and you will be asked for passphrase you specified when initially creating the key to unlock your private key. This is an extra security measure to ensure even when people managed to get your security key there still more work to do.
$ gpg --output doc.dec --decrypt doc.gpg You need a passphrase to unlock the secret key for user: "nkkkkk " 2048-bit RSA key, ID D8CB679E, created 2018-04-03 (main key ID E9F66E1F) gpg: encrypted with 2048-bit RSA key, ID D8CB679E, created 2018-04-03 "nkkkkk "
And, we have the clear text:
$ cat doc.dec This is a confidential doc

Sign & Verify

$ gpg --output doc.sig --clearsign doc You need a passphrase to unlock the secret key for user: "nkkkkk " 2048-bit RSA key, ID E9F66E1F, created 2018-04-03
$ cat doc.sig -----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 This is a confidential doc -----BEGIN PGP SIGNATURE----- Version: GnuPG v1 iQEcBAEBAgAGBQJaxCjbAAoJENnsH7Xp9m4fKB8H/Aqu6PZsnZfqjst+kNxJbNRj V2MryeO6l6K4UgPevH7C92qY1JEzUyVok2Eqecfb+rKwjYOzQGtAYa+nWVLsJMOi 5XvGJYNdLsMmuW4/dB8K2mnZXczaZpMKUab7LZ3BzQI5Kg5LYchMuwViL6f8PLEN KmAR3H3CQmR/ZsU5YHi4uy2Fq/ujMLhEt1Uu2qMhocwj1ZJfZj/aHsvl4A2YtlGD DmFDllFgv5MvTuAduBQ4jG+g09Jn9mJ0Cf7I6ozAbCxu+bm3vrkymYUqTvq2/szM zs55qGxz5oJTnzjOf0+N95e9LDtzrTKoNzZfDzU0SdJDnG+h0E1hpZBrR5Xi+Zo= =ut47 -----END PGP SIGNATURE-----
To verify
$ gpg --verify doc.sig gpg: Signature made Wed 04 Apr 2018 11:22:35 AM AEST using RSA key ID E9F66E1F gpg: Good signature from "nkkkkk "
If someone managed to modify the signed message, say adding "oh no" after "This is a confidential doc".
$ cat doc.modified -----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 This is a confidential doc oh no -----BEGIN PGP SIGNATURE----- Version: GnuPG v1 iQEcBAEBAgAGBQJaxCjbAAoJENnsH7Xp9m4fKB8H/Aqu6PZsnZfqjst+kNxJbNRj V2MryeO6l6K4UgPevH7C92qY1JEzUyVok2Eqecfb+rKwjYOzQGtAYa+nWVLsJMOi 5XvGJYNdLsMmuW4/dB8K2mnZXczaZpMKUab7LZ3BzQI5Kg5LYchMuwViL6f8PLEN KmAR3H3CQmR/ZsU5YHi4uy2Fq/ujMLhEt1Uu2qMhocwj1ZJfZj/aHsvl4A2YtlGD DmFDllFgv5MvTuAduBQ4jG+g09Jn9mJ0Cf7I6ozAbCxu+bm3vrkymYUqTvq2/szM zs55qGxz5oJTnzjOf0+N95e9LDtzrTKoNzZfDzU0SdJDnG+h0E1hpZBrR5Xi+Zo= =ut47 -----END PGP SIGNATURE-----
The verification will fail and the receiver will know the message can't be trusted.
$ gpg --verify doc.modified gpg: Signature made Wed 04 Apr 2018 11:22:35 AM AEST using RSA key ID E9F66E1F gpg: BAD signature from "nkkkkk "

Sending your public key to Key Server and let the whole world know

Sending public key using email doesn't sound quite cool in the modern age. You can publish your public key in GPG key servers so others can search and import your public key from the server.
Send it,
$ gpg --keyserver pgp.mit.edu --send-keys E9F66E1F gpg: sending key nk@email.com to hkp server pgp.mit.edu
Search it,
$ gpg --keyserver pgp.mit.edu --search-keys nk@email.com gpg: searching for "nk@email.com" from hkp server pgp.mit.edu (1) nkkkkk 2048 bit RSA key E9F66E1F, created: 2018-04-03, expires: 2018-05-03 Keys 1-1 of 1 for "nk@email.com". Enter number(s), N)ext, or Q)uit > Q
We typed Q)uit here, so we just search the key without importing it. If we had typed the 1, which is the key number, the key E9F66E1F would have been imported.

You can also import the key using keyId (not user id) directly.
$ gpg --keyserver pgp.mit.edu --recv-keys E9F66E1F gpg: requesting key E9F66E1F from hkp server pgp.mit.edu gpg: key E9F66E1F: "nkkkkk " not changed gpg: Total number processed: 1 gpg: unchanged: 1

Summary

With GPG, you'll be able to encrypt and sign your data and communications, improving security and protecting privacy. Plus, it makes you look cool or "geeky" by showing a GPG public key fingerprints in your name card or twitter intro, even you have never ever used it.

FC55 55E3 7C49 FE30 1A5D E8E9 D9EC 1FB5 E9F6 6E1F