Menu

An Introduction to Public Key Encryption

By Colin Wilson on 09 March, 2015

An Introduction to Public Key Encryption

Introduction

A long time ago, in a galaxy far, far away, I remember when I first learned of public key encryption. I also remember it took me longer than I’d like to admit for exactly how it works to click.

Encryption tends to be one of those techs that scares people. Many assume it’s a technology accessible only to genius level mathematicians, spy agencies, or crypto nerd hackers in dark basements. Yep. Hollywood is mostly to blame for this misconception.

Public key encryption is in fact frequently used by many outside the realm of fantasy. Regular privacy conscious individuals, journalist communicating with sources and companies protecting sensitive data or trade secrets all have a vested interest in public key encryption.

This post is my attempt to help beginners grasp the very basics of public key encryption and its use.

(Most of the functions below are carried out using GPG via the (Linux) terminal or Windows command prompt.)

What is Public Key Encryption?

Keys are basically unique digital files, which, when used in conjunction with encryption software allows you to encrypt and decrypt data.

This is what your typical public key looks like:

-----BEGIN PGP PUBLIC KEY BLOCK-----
Version: GnuPG v2.0.27

mQINBFRkpQIBEACpCgMcMOEOE5Mb4kkGqztIyybE50I3Kh0/ERYE8AIPeWMy9j1u
3tUdtUntzbLVTec3BOS9u3m+N6LBdu8IJ3cPX1JQAJtKlOp3pxGPvS2e/ejxSQcf
y0U8SMkXgCFYd4wwY6RlzAFCcMiWW+lnzQVuCaz4XlDd6lmqRE5jtCXJSDh2dGK9
sSnfD1ojCpNRDVu0x7KCg2S2XymHlt6R0RsGEUdHYGpdU0jop0kj3LiXoPE4pNVb
cCYo8PGI/dsXKEPInmr39m6WhE4/6DvdZodf9UOpbae4v7qfOewpsgYA6VanRFrU
uYCSfYWjeCuXixLxHXHrgQ6QRUu9jEyi4iM8J7GG3cu+cRxBquujMxRETJo1JfZg
CUSDjJDW/OA4zVkZqmhWn7xqqrgv4+uMymgP2/j2mudvYHxXMr0lTTqHlgI/VSLp
GyMFCQeEzgAGCwkIBwMCBhUIAgkKCwQWAgMBAh4BAheAAAoJEG00W0mPrOGmO8gP
/3fFZDoHxtUku30C4x9zK/eUJjgfdaG0W1VD/6DlA9gyumIVBo5e82DSE7YCoCBI
DEYfgPoYTMbnTyMu3kLGoBHePyNjs2spBRUCx1Tl/UvyckKXDdl4kOeedw+4HR
Vf2lPJ9hDocVFrTB4CZWlureKE0ucZ+k4DBpExZ/Jr2JZuax9htC
=7Ue5
-----END PGP PUBLIC KEY BLOCK-----

Public key encryption uses two separate but related keys known as a key pair to encrypt and decrypt data. The two keys are known as a public and private key. The public key, as it’s named is - public, it’s the key that you make available to anyone/everyone. While the private key as suggested is the key that you keep private and reveal to no one.

Your public key is the part that you and everyone else can use to encrypt data (decrypt-able only by your private key).

Encrypting & Decrypting Data

Here’s an example of how public key encryption works.

Let’s say Edd Snowballs wants to send you a file that he wants only you to be able to read/open. You can email Edd your public key without any security fears since it’s only use is for the encryption of data. Once Edd encrypts his file using your public key, he can email it you safe in the knowledge that only your private key can decrypt the file and view its contents.

Once you receive Edds encrypted file. You can now go ahead and decrypt it using your private key.

Data encrypted via your public key can only be decrypted using your private key. As you’ve no doubt guessed, keeping private keys safe is paramount to the integrity of secure communications between parties using public key encryption. If you were to lose your private key, anything that has been encrypted via your public key will remain locked, comparable to locking something in a vault and losing the physical key.

Validating your Identity

Your private key can also be used to validate your identity. This is called ‘digital signing’. You can ‘sign’ a message or file prior to sending it using your private key;

The receiver can then use your public key to verify that the file was signed by your private key.

This prevents third-parties from impersonating you. Digital signing also has the added benefit of verifying that the integrity of the sent data has not been compromised, damaged, or tampered with in anyway.

This again highlights how important a role your private key plays in identifying you as well as the encryption/decryption process. Any party gaining access to your private key would not only be able to decrypt data intended for you, worse yet, they’d be able to impersonate you.

In short. KEEP YOUR PRIVATE KEY SAFE, and never, under (almost) any circumstances give it to anyone.

GPG

GnuPG (or GPG) is an open source alternative to PGP (Pretty Good Privacy).

GPG is installed by default on most Linux distributions and Windows users can access GPG via GPG4win (GNU Privacy Guard for Windows) for free.

You can check whether GPG is install on your system by opening a terminal on Linux (or command prompt in Windows) and typing gpg --version.

# gpg --version
gpg (GnuPG) 1.4.12
Copyright (C) 2012 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://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: ~/.gnupg
Supported algorithms:
Pubkey: RSA, RSA-E, RSA-S, ELG-E, DSA
Cipher: 3DES, CAST5, BLOWFISH, AES, AES192, AES256, TWOFISH, CAMELLIA128,
        CAMELLIA192, CAMELLIA256
Hash: MD5, SHA1, RIPEMD160, SHA256, SHA384, SHA512, SHA224
Compression: Uncompressed, ZIP, ZLIB, BZIP2

The above shows that GnuPG version 1.4.12 is installed.

1.Generating a Key Pair

The following command generates your key pair:

# gpg --gen-key

Choose the following options when prompted:

After entering your passphrase the system will generate your keys using entropy. Entropy is basically a term used to describe the randomness involved in generating your outputted keys. This process utilizes random activity on your system such as keyboard, mouse and hard disk activity. Therefore using these as much as possible during key generation will reduce the time required to create your key pair.

Example output:

# gpg --gen-key
gpg (GnuPG) 1.4.12; Copyright (C) 2012 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.

gpg: directory `/root/.gnupg' created
gpg: new configuration file `/root/.gnupg/gpg.conf' created
gpg: WARNING: options in `/root/.gnupg/gpg.conf' are not yet active during this run
gpg: keyring `/root/.gnupg/secring.gpg' created
gpg: keyring `/root/.gnupg/pubring.gpg' created
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) 4096
Requested keysize is 4096 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) 0
Key does not expire at all
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) <heinrichh@duesseldorf.de>"

Real name: Edd Snowballs
Email address: edd@moscow.org
Comment:
You selected this USER-ID:
    "Edd Snowballs <edd@moscow.org>"

Change (N)ame, (C)omment, (E)mail or (O)kay/(Q)uit? O
You need a Passphrase to protect your secret key.

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: /root/.gnupg/trustdb.gpg: trustdb created
gpg: key A7C35021 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:   1  signed:   0  trust: 0-, 0q, 0n, 0m, 0f, 1u
pub   4096R/A7C35021 2015-03-10
      Key fingerprint = F192 EFB5 8FC2 0F9E 6C20  8AE9 2596 CBB1 A7C3 5021
uid                  Edd Snowballs <edd@moscow.org>
sub   4096R/C55D9269 2015-03-10

That’s it. You’ve now created a key pair. You should now immediately generate a revocation certificate.

2.Generating a Revocation Certificate

So we’ve established the importance of keeping your private key safe? Well what happens if you suffer the misfortune of losing your private key or it’s somehow compromised? How can you inform people that your public key is no longer valid, and to cease any further use of it? This is where Revocation Certificates come in.

Revocation certificates allow you to revoke the validity of your key pair. This makes revocation certificates just as important as your private key, and they should always be generate at the same time you create your key pair.

Type the following to generate your revocation certificate:

# gpg --output my_rev_cert.asc --gen-revoke your_email@address.com

You’ll be prompted to enter a reason for generating the revocation certificate. Since we’re creating it ahead of time, any option you select here is fine. You’ll also be prompted to enter your passphrase, and a optional comment of some kind. After confirming these choices, your revocation certificate will be generated to the file my_rev_cert.asc. Copy and store it in a secure location.

Example output:

# gpg --gen-revoke edd@moscow.org

sec  4096R/A7C35021 2015-03-10 Edd Snowballs <edd@moscow.org>

Create a revocation certificate for this key? (y/N) y
Please select the reason for the revocation:
  0 = No reason specified
  1 = Key has been compromised
  2 = Key is superseded
  3 = Key is no longer used
  Q = Cancel
(Probably you want to select 1 here)
Your decision? 0
Enter an optional description; end it with an empty line:
>
Reason for revocation: No reason specified
(No description given)
Is this okay? (y/N) y

You need a passphrase to unlock the secret key for
user: "Edd Snowballs <edd@moscow.org>"
4096-bit RSA key, ID A7C35021, created 2015-03-10

ASCII armored output forced.
Revocation certificate created.

Please move it to a medium which you can hide away; if Mallory gets
access to this certificate he can use it to make your key unusable.
It is smart to print this certificate and store it away, just in case
your media become unreadable.  But have some caution:  The print system of
your machine might store the data and make it available to others!

If you ever need to revoke your key pair, you can do so by importing the revocation certificate:

# gpg --import my_rev_cert.asc

Your key is now revoked.

You can also submit your revoked key to a keyserver to publicise it’s revocation status (section 4 explains keyservers):

# gpg --keyserver pgp.mit.edu --send-keys your_email@address.com

Now anyone running a search for this key will see *** KEY REVOKED *** on the first line of the details and see that the key is no longer valid.

3.Exporting Your Key Pair

Now that you’ve generated your key pair and revocation certificate, you can export them to files for backup and safe keeping.

# gpg --export-secret-keys --armor your_email@address.com > your_email@address.com.private.gpg-key

# gpg --export --armor your_email@address.com > your_email@address.com.public.gpg-key

The above commands will export your key pair to two separate files, one your private key, and the other your public key. Keep your private key along with the revocation certificate you generated earlier in a safe place - Not on your laptop or workstation. It’s also good practice to store your private key and revocation certificate in separate locations.

4.Importing Public Keys

Let’s not forget that the whole purpose of public key encryption is to provide a means of secure communication between parties. Importing the public keys of others allows us to get started with this.

After downloading someone’s public key file, you import it using the following command.

# gpg --import edd-snowballs-public-key.asc
gpg: key A7C35021: public key "Edd Snowballs <edd@moscow.org>" imported
gpg: Total number processed: 1
gpg:               imported: 1  (RSA: 1)

Many people make their public keys available via KeyServers. These are essentially online databases of public keys. You can import public keys from keyservers directly via the command line.

The follow command will search for my public key on the MIT public keyserver:

# gpg --keyserver pgp.mit.edu  --search-keys colin wilson

The search result will give you the option of choosing which key you wish to import.

After you’ve imported someone’s public key, the next step is to verify and sign it.

5.Key Verification & Signing

Once you’ve imported a public key, signing it tells GPG that you’ve verified the key as being associated with the person it identifies, and that you trust they are who they claim to be. The best way to verify someone’s public key is to meet with them in person (although this may not always be feasible, practical, or even safe!). If meeting in person is not an option, the next best thing is to find an alternative means by which you can guarantee you’re communicating with the public keys rightful owner. You can then verify the keys ‘fingerprint’ with them.

So what’s a public key ‘fingerprint’? The fingerprint is a unique hash associated with, and generated from the public key itself. You can view a public keys fingerprint via the --fingerprint option.

# gpg --fingerprint edd@moscow.org
pub   4096R/A7C35021 2015-03-10
      Key fingerprint = F192 EFB5 8FC2 0F9E 6C20  8AE9 2596 CBB1 A7C3 5021
uid                  Edd Snowballs <edd@moscow.org>
sub   4096R/C55D9269 2015-03-10

So having obtained a persons public key. You can contact them (say via phone if not in person) and verify that the fingerprint they give you matches the one you have, hence they are the rightful key owner.

N.B. When verifying public key fingerprints, be sure to verify the full fingerprint and not just the 32bit version (last 8 characters). See here https://evil32.com for why.

Ok. So you’ve imported someone’s public key and successfully verified it belongs to them. Now it’s time to sign their public key.

Use --sign-key to sign someone’s public key:

# gpg --sign-key joe.bloggs@home.com

That’s it. GPG now sees this public key as verified and trusted by you.

So after importing, verifying and signing someone’s public key. You can now export the signed key to file:

# gpg --export --armor joe.bloggs@home.com

And/or send it to a keyserver:

# gpg --keyserver pgp.mit.edu --send-keys joe.bloggs.home.com

A Note about Key Signing

Key signing and having your own public key signed by others contributes to what’s known as a Web of Trust (WoT). Signing the public key of someone you trust, allows others who trust you, to also trust the person who’s key you’ve signed, since others will know that (hopefully) you would not have signed it without carefully verifying their identity.

This works both ways. Someone who’s signed your public key is effectively showing others that they trust and have verified it belongs to you, thus making it more likely for those who trust that individual to also trust you (and your public key).

The above illustrates Edds wish to communicate with Joe. But, Edd has no means of meeting or contacting Joe to confirm that his public key actually belongs to him. Edd has however met with, and verified the identity of Laura who has signed Joe’s public key after meeting him in person and confirming his identity. Edd can now place a considerably higher level of trust in Joe’s public key than before, since he’s confident Laura would not have signed it without vetting Joe’s identity. Thus, Edd can now communicate with Joe via his trust in Laura’s signing policy.

Behaviour and policies such as this are the foundation upon which a Web of Trust is built. They enable you to verify, sign public keys, and communicate with those who you’re not able to personally verify.

Here’s an example of what a signed public key entry looks like on https://pgpkeys.mit.edu:

pub  4096R/DDF73B36 2013-10-28

uid Laura Poitras <laura@freedom.press>
sig  sig3  DDF73B36 2014-09-26 ___ 2017-10-28 [selfsig]

uid Laura Poitras <laura.poitras@theintercept.com>
sig  sig3  DDF73B36 2014-03-28 ___ 2017-10-28 [selfsig]
sig  sig3  DDF73B36 2014-03-28 ___ 2017-10-28 [selfsig]
sig  sig   7BEDFED8 2014-06-04 ___ ___ Arthur Klein (Content Creator) <imagine@riseup.net>
sig  sig3  DDF73B36 2014-09-26 ___ 2017-10-28 [selfsig]
sig  sig   EBDC9F9A 2014-11-24 ___ ___ Bryan Belt (Ultra) <privacy@anche.no>
sig  sig   CD36DD5D 2014-11-24 ___ ___ Bryan Belt <privacy@anche.no>
sig  sig3  A9363692 2014-12-09 2018-12-09 ___ Prince Serna <prince@firstlook.org>

As you can see, Laura Poitras' public key has been signed by three people. Arthur Klein, Bryan Belt and Prince Serna. Meaning all three have verified and trust that this public key indeed belongs to Laura Poitras.

You may have figured out that signing someone’s public key without verifying their identity is not only detrimental to others, but also has a negative impact on your own trust level. Since others may refuse to be associated with you (or sign your public key) due to your disregard for a proper signing policy.

6.Encrypting & Decrypting Data using GPG

Encrypting Files & Documents

The `--encrypt` option allows you to encrypt files and documents for intended recipients using their public key.

Using Edd Snowballs' public key you could encrypt a file before sending it to him:

# gpg --encrypt -r edd@moscow.org file.zip

You’ll now have an encrypted version of the file named file.zip.gpg which can only be decrypted by Edd. The -r recipient option uses Edds email address to identify his public key as the one to use when encrypting the file. You can also use the key ID (last 8 characters of the key fingerprint) to select a public key as opposed to the email address.

It’s possible to add multiple recipients when encrypting. This allows you to encrypt a file that more than one person (including yourself) can open.

# gpg -r joe.bloggs@home.com \
	  -r colin@infinitysgame.com \
	  -r edd@moscow.org \
	  --encrypt file.zip

Edd, Colin and Joe Bloggs would all be able to decrypt the file file.zip.gpg generated by the above command.

Encrypting messages is very similar.

# gpg --encrypt --sign --armor -r joe.bloggs@home.com msg.txt

The msg.txt text file above is encrypted using Joe Bloggs' public key and signed (verified as coming from you) using your private key. The --armor option forces the encrypted file output to a text-based (ASCII) format which you can then cut-and-paste into an email to Joe.

Decrypting Files & Documents

Decrypting files and messages you receive is as simple as:

# gpg msg.txt.asc
# gpg file.zip.gpg

The above commands will prompt you to enter your passphrase before decrypting the file or message.

Conclusion

This post only scratches the surface of GPG’s capabilities. There’s a wealth of advanced options not mentioned in this post. But hopefully if you’ve reached this far, you’ve at least gained a working knowledge of how public key encryption works, and how to use it (via GnuPG/GPG).

Spot any mistakes or have any suggestions on how this article can be improved? Please do leave a comment or drop me an email.

My next post will focus on some of the more advanced features of GPG.


Article originally posted on infinitysgame.com (my old domain). This repost is the unaltered original content except for formatting

Comments

netlify logo

Copyright © Colin Wilson 2021 (5b94008)