Pretty Good Privacy (PGP) is a cryptographic program that allows users to sign, encrypt and decrypt data. It was developed in 1991 by Phil Zimmerman, an anti-nuclear activist who wanted a way for like-minded persons to communicate securely. While his code has always free for non-commercial use, the project’s history have led to concerns about patent issues. The Free Software Foundation (FSF) developed its own version, GnuPG (GPG), that is fully compatible with the OpenPGP standard.
How does PGP work?
PGP uses both public key and conventional cryptography to protect information:
-
With conventional cryptography, a single key is used to encrypt and decrypt information. Conventional cryptography is extremely fast for computers, and it is possible to use a strong key (one which couldn’t be guessed in a million years, even if using all the computing power on Earth). However, it suffers from the fact that the secret key must remain secret to all but persons communicating with it. If anyone else were to have they key, they could copy and decrypt sensitive information. Thus, protecting and transmitting the key securely is a problem in these schemes.
-
With public key cryptography, a user generates two keys: one for encryption and one for decryption. The key used for encryption is called the “public key,” and the one for decryption is called the “private key.” In this scheme, a user publishes his or her public key for all to see. Anyone can use the public key to encrypt information, but only someone with the private key can decrypt it. This mitigates the problem of secure key transmission; two parties can send each other their public keys without worrying about whether they’re captured along the way. Their communications will remain private, because anyone with just the public key can’t decrypt anything. The downside is that these schemes are more computationally intense, and thus slower to compute.
PGP accepts plaintext data and compresses it to obfuscate any patterns that could be divined through cryptoanalysis. It then generates a one-time random session key, and uses it to encrypt the compressed data (conventional cryptography). Finally, it encrypts the session key using the target’s public key. Then the encrypted data and encrypted session key are transmitted to the recipient.
The recipient uses their private key to decrypt the session key (slow). Then they can use the session key to decrypt the data (fast). The benefit here is that the data remains secure in transmission, and can only be decrypted by the intended recipient. The means of encrypting and decrypting are such that PGP provides great speed without sacrificing security.
PGP stores keys in files called keyrings. The public keyring holds the public keys of your contacts, while the private keyring holds your private keys in an encrypted format. Your public keys are made available to your contacts so they can encrypt things that only you can read. If you lose your private keyring or the passphrase to decrypt those keys, you lose the ability to decrypt anything someone sends you using your old public keys.
What is PGP used for?
There are a number of things you can do with PGP. The two most common are:
-
Encrypt/decrypt emails and files. Let’s say you want to talk privately with Bob over email, but Bob’s sysadmin, Eve, is a bit of a snooper. You and Bob exchange public keys; if Eve sees these, they tell her nothing. You write Bob a message, and PGP compresses the message and encrypts it with Bob’s public key. You send off the resulting ciphertext. Bob receives the message, downloads it locally and uses his private key to decrypt and read it. Eve only sees the ciphertext and has no way to read it. A similar approach is taken if you want to send Bob a file that you don’t want Eve to download and look at.
-
Digitally sign documents. Public key cryptography has the interesting feature of being able to work in reverse to prove one’s identity. That is, if Bob sends you a message and you want to know it really came from Bob, he can use his private key to encrypt a one way hash of the message. If the public key you have for Bob is capable of decrypting that info, AND your hash of the message matches the one Bob sent, then you know it must have come from Bob and was not changed along the way.
PGP Keys
If you’ve ever set up public/private keypairs in SSH, then you’ll have some mental model of how PGP sets up keys. Like SSH keys, PGP allows you to generate a passphrase, so that even if the private key is stolen the thief could not use it to decrypt anything.
However, PGP offers a number of additional features and modeling not present in SSH keys:
-
Profiles. When you create a PGP keypair, you actually create a mini profile for yourself. PGP is not only about encryption, but also about identification. This feature allows you to attach a name, email and comment to an identity.
-
Avatars. You can actually add an image or avatar to your public key. Since this key is publicly distributed, some services can display the embedded image along with the public key. It’s not strictly necessary, and it does increase the length of the public key. So it’s more of a “nice to have.”
-
Sub-keys. Subkeys are just like normal public/private keypairs, except they are bound to a master keypair. This is immensely helpful in key management, since you can use different subkeys for different devices. Your master keypair is the identity you have created; if the private key is lost or compromised, you’re hosed. You’ll need to create a new identity and start over.
With subkeys, you can keep a master keypair in a safe location (like an encrypted partition, or a thumb drive in a safe), and only take it out to generate, modify, or revoke subkeys. If any of those subkeys are compromised or lost, you can simply revoke and regenerate them, but your identity is not affected. -
Revoke/Expire. PGP keys and subkeys can be revoked or set to expire. The use case for the former might be a situation in which the private key has been compromised. In that case, information encrypted with the public key can be decrypted by someone other than the intended recipient. Revoking the key is like an announcement that the old public key should no longer be used.
Expiration dates on keys are about long term security. The longer a keypair is in use, the more likely it is to be compromised in some way, either by hacking or a cryptographic break. Setting the expiration date gives a potential attacker a smaller window in which to compromise the private key.
PGP Security Models and the Web of Trust
PGP was originally developed to ensure secure communication over an insecure medium, and it accomplishes the immediate task quite well. However, one problem with PGP keys is that anyone can generate them. There’s nothing stopping me from creating an identity named “Barack Obama <[email protected]>” via PGP, and disseminating the resulting public key far and wide, even though I am not Barack Obama. So how do we validate that a public key actually belongs to the person it purports to represent?
There are a few ways of handling this. One is to create a centralized certificate authority (CA) that signs a public key, affirming its authenticity. Everyone trusts the CA, so if you have a certificate signed by the CA, you are immediately trusted. Think of this like getting your driver’s license from the DMV; you show up with a number of documents proving you are who you say, the agent verifies them, and then hands you a license. Then when you show that license to someone else, they can reasonably trust that you are who you say. Similarly, a CA makes people prove their identity before signing their public key, and then others can trust said key based on the fact that the CA has endorsed it.
The CA model has a number of problems. A major one is that it can result in trust hierarchies, in which a user who compromises the private key of one of the authorities can then use it to sign other, illegitimate keys. The false keys are subsequently trusted by everyone who trusts the CA. This poses security risks for a potentially large pool of users.
An alternative model, and the one the PGP employs, is a decentralized social map known as a “Web of Trust.” In this model, each user’s keyring is populated with the public keys they have added from other users. The keyring indicates how much the owner trusts the authenticity of each public key. There are two parameters for “vouching” for another person’s public key:
Validity
When Alice signs Bob’s key, she is affirming Bob’s relationship to the key on file. That is, Alice is saying that she is convinced that Bob’s key actually came from Bob and not someone pretending to be Bob. There are two ways that GPG will consider a key valid:
- The key is signed by the owner of the keyring
- The key is signed by the owners of other keys in the keyring who are trusted (discussed in a moment)
Any key in the keyring that does not meet one of those two conditions is considered invalid. In other words, it is assumed to not be from the person it purportedly represents.
Trust
Also called “owner-trust,” to distinguish from “key trust.” This parameter expresses how much Alice trusts Bob to verify other people’s identities. If Alice receives a public key from Charlie that has been signed by Bob, she can gauge how likely it is that Charlie is who he presents himself to be based on how much she trusts Bob.
There are several levels of trust, and keyring owners can set how much they trust a given key. The trust level indicates how many other users are needed to vouch for the key in order for it to be accepted. There are 4 distinct levels of trust:
- Ultimate. If you have the corresponding secret key to this public key, then it is ultimately trusted. So basically, keys you generate yourself are ultimately trusted keys. Ultimately trusted keys are automatically valid.
- Full/Complete. Full (also called “complete”) trust is for keys that you are completely confident are valid. This might mean that you know the owner personally, or checked their documentation, before confirming their key. By signing a key in your keyring, you are conferring full trust in that key. Otherwise, it needs to be signed by at least two keys in your keyring that have your complete/full trust. Completely trusted keys are valid.
- Marginal. Marginal trust is reserved for keys that you’re not totally convinced are valid; like a key that you found on a person’s website, but haven’t confirmed the person’s identity yet. At least four keys with marginal trust have to sign a fifth key in order for that fifth key to be valid.
- Untrusted. Untrusted keys are for situations where you receive a key but have absolutely no way to confirm the relationship of the owner. Untrusted keys are always invalid.
Keyservers
One downside to the Web of Trust model is that there isn’t a great way to pass along updates to others who have your public key on their keyring. For example, Alice and Bob are sitting together; Alice generates a keypair and passes along the public key to Bob. Because Bob knows that this key absolutely belongs to Alice, he signs her public key on his keyring. This signature remains on Bob’s computer and doesn’t get automatically transmitted back to Alice or anyone else.
Alice then sends her public key to Bob’s friend, Charlie. Charlie has Bob’s key on his keyring, which he trusts completely. When Alice’s email comes in, Charlie doesn’t know how much to trust it; if her key had Bob’s signature, then Charlie would immediately trust Alice’s key. But Bob’s signature is local to Bob’s computer, so all Charlie sees is a public key with no signatures on it. He then refuses to trust it.
In the case of Alice, Bob and Charlie, the situation is easily resolved once Bob gives Charlie a call and vouches for Alice. But imagine the headache this would be if you have any more than 3 people. If every time a key was updated, the changes would have to be manually sent to everyone in the web. This is the type of problem the keyservers were designed to solve.
Keyservers do exactly what it sounds like - serve keys. More specifically, they’re like directories for public PGP keys. Generally, they are linked together, so that sending your key to one server will cause it to become visible to all of them in a short period. The nice thing about keyservers is that they update existing public keys that have changed. So if you update your information and pass along the
So in the example above, Alice could place her key on a keyserver; once Bob signs it, he can send the update to the keyserver. Then, when Charlie checks Alice’s key against the keyserver data, he’ll see Bob’s signature and know that it’s okay to fully trust Alice’s public key.
Caveat emptor There are a few reasons to not use a keyserver. They are:
-
Your public key is tied to an email address, and spammers are known to harvest emails from keyservers. You can mitigate this by generating a keypair that uses a fake email address, but this limits your ability to comminicate with others who don’t know how else to reach you.
-
You (generally) can’t delete your public key from a keyserver. The major keyservers are all linked, and deleting your key from one will not delete it from any others. Just understand that you can’t recall a public key (but you can revoke it)
-
Your public key contains signatures of people in your web of trust. Analysts can gain useful information about you from mapping out those relationships. For most people, this isn’t a big deal. But if you work in security or are using PGP to mask your identity, analyzing those relationships can reveal information about who you are.
And possibly others. Keyservers can be a big help, a headache, or a massive security threat, depending on your use case and configuration. Develop a clear picture of how you plan to use PGP before you decide to upload your information publicly.
Secure setups
Ideally, you want a master keypair which acts as your primary identity, with subkeys for different applications. A common scenario is to have a subkey on a laptop, while the master keypair is saved to someplace more secure. Thus, if the laptop is ever stolen, you can revoke the subkey without revoking the entire identity.
When you’re generating these keys, they should be as secure as possible. This means maximum key lengths and secure crypto functions. There are four pieces here:
-
Ciphers. PGP supports a number of different ciphers. AES/Rijndael and 3DES/DES are the most common. Blowfish, CAST5 and the DES variants have small block sizes, and should be avoided. AES is fast, and offers up to 256 bit key lengths. Twofish potentially has a higher security margin than AES, and is slightly faster than AES for key sizes of 256 bits
If you’re doing a lot of communicating with PGP, you should be aware that it is possible for someone to capture the data and simply store it for a period until computers become powerful enough to guess your keys, or there is a cryptographic break in the cipher. To avoid this, or at least delay the inevitable, you should use the strongest ciphers with the longest possible key lengths. So really, you want either AES256 or TWOFISH.
The question at this point should now be how you’re planning to use the keys. If you’re using it for simple communication, go with Serpent. If you’re encrypting lots of large files and such, use AES. -
Digest/Hash functions. The digest is used to create a string of fixed length that is unique to the contents of the message. Changes to the message will change the hash. However, no known hash function is “perfect;” there are ways to modify a message such that the new hash is the same as the original hash. This is called a hash collision.
We want a digest function that is secure from this and other attacks. This eliminates MD5 and SHA1. Finally, we want a function with at least 256 bit lengths. So SHA512/384/256 are the contenders here. -
Compression. PGP uses compression to obfuscate the contents of a message before encrypting it. The compression algorithm you use shouldn’t really matter as long as you are using one.
-
Public key creation. There are a few ways to generate public/private keypairs, some of which are stronger than others. RSA is the most common, as it’s strong and there isn’t a known method for cracking it. In fact, determining the private key from only a public key is a major problem in mathematics. So RSA is fine.
PGP also supports other methods, such as DSA and ELG, which are generally faster, but much weaker. Elliptic curve methods (ECDH, ECDSA and EdDSA) are stronger, with EcDSA being a much more secure implementation of DSA (without NSA involvement).
The main difference between RSA and EdDSA is the key length needed to achive the same security margin. Basically, you would need an RSA key with 3072 bits of length to get the same security margin as 256 bits of EdDSA. So a basic EdDSA key will provide a bit more speed than an RSA key of an equivalent security margin. However, RSA keys can be up to 4096 bits in length, so you can get a higher security margin than EdDSA provides, albeit with a relative loss of speed.
Unfortunately, as of this writing, GnuPG doesn’t support EdDSA, so RSA is the clear winner. That will change eventually, though.
For now, the following configuration will provide the best security:
Pubkey: RSA
Cipher: TWOFISH
Hash: SHA512
Compression: ZIP
Wrapping up
Hopefully, this post has given you a solid understanding of what PGP is and how it works. It’s a bit longer than normal, coming in at over 3,000 words, but that’s the nature of security. In my next post, I’ll talk about some questions to ask yourself before creating a PGP identity.