From charlesreid1

GPG (Gnu Privacy Gard) is a security program that can be used to do many different things; sign files, hash files, encrypt and decrypt files, etc.

Installation

Installation can either be easy (when you run configure, everything goes fine, and you can do the usual make/make install thing), or it can be hard (you'll have to install a bunch of libraries sequentially by hand).

Configure (The Easy Way)

To configure GPG:

# configure
# make
# make install

./configure \
 --prefix=$HOME/pkg/gpg/x.y.z

Then run make and make install. If it runs with no errors, you're in luck: it ran the easy way.

Configure Pointing to Libraries (The Hard Way)

The above procedure may not work with newer versions (see #Missing Libraries error below). In that case, you might have to specify explicitly the location of some libraries (and install said libraries). These libraries include libgpg-error, libgcrypt, libassuan, and libksba libraries, and pth.

Install libgpg-error

Download this library here: http://www.gnupg.org/download/#libgpg-error

Unzip it and run the following configure script from within its source directory.

#!/bin/sh

./configure --prefix=${HOME}/pkg/gpg/libgpg-error/x.y.z
  \
  && make -j2 all \
  && make install \
  && make clean \
  && ln -fs ~/pkg/gpg/libgpg-error/{x.y.z,std}

Install libassuan

Download this library here: http://www.gnupg.org/download/index.en.html#libassuan

Run this from its source directory:

#!/bin/sh

./configure \
  --prefix=${HOME}/pkg/gpg/libassuan/x.y.z \
  --with-gpg-error-prefix=${HOME}/pkg/gpg/libgpg-error/std
  \
  && make -j2 all \
  && make install \
  && make clean \
  ln -fs ~/pkg/gpg/libassuan/{x.y.z,std}

Install libgcrypt

Download this library here: http://www.gnupg.org/download/index.en.html#libgcrypt

Run this from its source directory:

#!/bin/sh

./configure \
  --prefix=${HOME}/pkg/gpg/libgcrypt/x.y.z \
  --with-gpg-error-prefix=${HOME}/pkg/gpg/libgpg-error/std
  \
  && make -j2 all \
  && make install \
  && make clean \
  ln -fs ~/pkg/gpg/libgcrypt/{x.y.z,std}

Installing libksba

Download this library from here: http://www.gnupg.org/download/index.en.html#libksba

Run this script from its source directory:

#!/bin/sh

./configure \
  --prefix=${HOME}/pkg/gpg/libksba/1.2.0 \
  --with-gpg-error-prefix=${HOME}/pkg/gpg/libgpg-error/std \
  \
  && make -j2 all \
  && make install \
  && make clean \
  && ln -fs ~/pkg/gpg/libksba/{1.2.0,std}

Installing pth

Download pth from here: ftp://ftp.gnu.org/gnu/pth/

Then run this script from its source directory:

#!/bin/sh

./configure \
  --prefix=${HOME}/pkg/gpg/pth/x.y.z \

then

make

make test

make install

ln -fs ~/pkg/gpg/pth/{x.y.z,std}

Install Gpg (FINALLY!)

Now you can finally install gpg, making sure to point at all those libraries you installed:

#!/bin/sh

./configure \
  --prefix=${HOME}/pkg/gpg/2.0.18 \
  --with-gpg-error-prefix=${HOME}/pkg/gpg/libgpg-error/std \
  --with-libgcrypt-prefix=${HOME}/pkg/gpg/libgcrypt/std \
  --with-libassuan-prefix=${HOME}/pkg/gpg/libassuan/std \
  --with-ksba-prefix=${HOME}/pkg/gpg/libksba/std \
  --with-pth-prefix=${HOME}/pkg/pth/std \

then do

make -j2

make install

ln -fs ~/pkg/gnupg/{x.y.z,std}

Errors

Missing Libraries

You may see an error about missing libraries libgpg-error, libgcrypt, and libassuan, like this:

configure: checking system features for estream
configure:
***
*** You need libgpg-error to build this program.
**  This library is for example available at
***   ftp://ftp.gnupg.org/gcrypt/libgpg-error
*** (at least version 1.7 is required.)
***
configure:
***
*** You need libgcrypt to build this program.
**  This library is for example available at
***   ftp://ftp.gnupg.org/gcrypt/libgcrypt/
*** (at least version 1.4.0 using API 1 is required.)
***
configure:
***
*** You need libassuan to build this program.
*** This library is for example available at
***   ftp://ftp.gnupg.org/gcrypt/libassuan/
*** (at least version 2.0.0 (API 2) is required).
***
configure:
***
*** You need libksba to build this program.
*** This library is for example available at
***   ftp://ftp.gnupg.org/gcrypt/libksba/
*** (at least version 1.0.7 using API 1 is required).
***
configure:
***
*** It is now required to build with support for the
*** GNU Portable Threads Library (Pth). Please install this
*** library first.  The library is for example available at
***   ftp://ftp.gnu.org/gnu/pth/
*** On a Debian GNU/Linux system you can install it using
***   apt-get install libpth-dev
*** To build GnuPG for Windows you need to use the W32PTH
*** package; available at:
***   ftp://ftp.g10code.com/g10code/w32pth/
***
configure: error: 
***
*** Required libraries not found. Please consult the above messages
*** and install them before running configure again.
***

If so, modify your configure script to explicitly point to these libraries. See #Configuring section above.

Some Security Theory

Public/Private Keys

Public and private keys are used to encrypt and decrypt information in a protected way, so that only the intended recipient can decrypt the file.

Let's consider the scenario where Alice is sending a file to Bob, with a middleman eavesdropper Eve.

Alice must combine her private key with Bob's public key to obtain a special combo-key. She then uses this combo-key to encrypt the file, and then she sends it to Bob.

Bob can then decrypt the file by combining his private key with Alice's public key, which creates a complimentary combo-key, and allows Bob to decrypt the file. In this way, Alice never knows Bob's private key, and Bob never knows Alice's private key, but they can still create complimentary combo-keys to encrypt/decrypt the file.

Evil Eve can also download the file sent from Alice to Bob, but because she does not have either Alice's private key, or Bob's private key, she cannot reconstruct the same combo-key to decrypt the file.

Public/Private Key Tasks

Generating a Public/Private Key Pair

To generate a private key,

$ gpg --gen-key
gpg (GnuPG) 1.4.10; Copyright (C) 2008 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?

RSA is stronger than DSA, so the default is highly recommended.

RSA keys may be between 1024 and 4096 bits long.
What keysize do you want? (2048) 

This is like asking, "How long would you like it to take to crack your private-key: 100,000 years, or 15,000 eons?

Requested keysize is 2048 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) 
Key does not expire at all
Is this correct? (y/N) y

Then it will ask for some identifying information. This is used to generate a public key, and it is important you give a unique name, email address, and comment, so that other people can identify your public key and distinguish it from others'.

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:
Email:
Comment:

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

Enter passphrase: 

Then it will generate your public and private keys:

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: key BB63D9F1 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

Then it will spit out a summary of your public key information.

List Keys in Your Keyring

Once you've created your public key, it will be added to your GPG key ring. You can see all the public keys on your GPG key ring using:

gpg --list-keys

Sharing Public Keys

Be careful about public keys - yes, they are nominally public, but you have to be careful that you have the CORRECT public key.

The reason is this - when you encrypt something, you use your own private key, and someone else's public key. To decrypt it, they need your public key and the private key that corresponds to the public key that you used.

The problem is this: if you inadvertently use the wrong public key, say a public key provided by a malicious man-in-the-middle, then whatever you encrypt can now be decrypted using nothing but your (publicly-available) public key. In other words, you don't need to keep the public key secret, but you do need to ensure you have the right public key corresponding to the right person, who you want to be able to decrypt it.

Here's what all of this means, in practice: DO NOT USE AN UNTRUSTED MEDIUM TO OBTAIN A PUBLIC KEY. That means, no email. The transfer method for public keys should be trusted. A file on a physical USB drive, a crossover ethernet cable between two computers, an SSH tunnel, an encrypted connection - these are all acceptable modes of transferring public keys, because a malicious person cannot tamper with the public key while it is in transit.

Public keys should either be shared in person via jumpdrive or local network transfer, via a trusted intermediate (who can sign a public key to confirm it is trusted by that person), or via a public key server.

Remember that GPG is all about trust. When you receive a public key, whoever owns the corresponding private key can decrypt everything that you encrypt using that public key, so you should be absolutely sure that you trust any public key that you receive and use to encrypt something.

Export ASCII Public Key

If you want to share your public key with others, you can output your public key in ASCII format, to share as a text file:

gpg --armor --output my_pubkey.txt --export 'Your Name'

or, shorter,

gpg -a -o my_pubkey.txt --export 'Your Name'

Remember, this is public, so you don't have to keep it a secret, but you want to make sure that anyone using your public key actually gets YOUR public key, and not a malicious man-in-the-middle's public key.

Import ASCII Public Key

You can import others' ASCII public keys into your GPG key ring using the --import option:

gpg --import friend_pubkey.txt 

Now when you list your public keys using gpg --list-keys, the new key will show up.

Putting Public Key on Public Key Server

You can send any of the public keys in your GPG by using the --send-keys option:

gpg --send-keys 'Your Name' --keyserver hkp://subkeys.pgp.net

Alternatively, some public key servers (like the PGP Key Server) have convenient web interfaces where you can copy and paste your ASCII public key.

Networks of public key servers often share keys, so your key will probably be propagated to other key servers.

Obtaining Public Keys from Public Key Server

You can obtain public keys from a public key server by using the --search-keys option:

gpg --search-keys 'name@email.com'

To specify a key server, use flag --keyserver hkp://subkeys.pgp.net

Alternatively, some public key servers will have web interfaces for searches.

Putting a Protected Private Key on a Jump Drive

http://lists.gnupg.org/pipermail/gnupg-users/2008-May/033426.html

Encryption Tasks

Encrypting/Decrypting Files

This is a method for encrypting and decrypting files using GPG. This is a handy trick if you want to store all of your usernames and passwords in a file and want to protect it via encryption (using your own public key), or if you want to encrypt a secret message to your school buddy using his or her public key.

Encrypting With Keys

You can encrypt a file so that only someone else can open it. To do this, you must create a GPG private key and a GPG public key (see #References, and GPG Quick Start).

You can also encrypt a file for yourself, so that only your public/private keys can open it.

1. Make sure you have the public key of the individual you want to send the file to, by running

$ gpg --list-keys

2. Encrypt the file using the -e or --encrypt flag, and specify a recipient by putting their name (the one that shows up from their public key) after the -r or --recipient flag:

$ gpg --encrypt --recipient 'Name of Person' secret.txt

$ gpg -e -r 'Name of Person' secret.txt

This will output a file secret.txt.gpg; alternatively, specify the name of the output file using -o or --output flag:

$ gpg --encrypt --recipient 'Name of Person' secret.txt --output encrypted_secret.txt

$ gpg -e -r 'Name of Person' secret.txt -o encrypted_secret.txt

The encrypted file will look like nonsensical garbage if opened in a text editor.

3. Decrypt the file using the -d or --decrypt flag:

$ gpg --decrypt --output decrypted_secret.txt

$ gpg -d -o decrypted_secret.txt

If you don't specify an output file, then it will output to stdout. If you are paranoid, this is probably not the best idea, since it is vulnerable to over-the-shoulder peeking. If you are extremely paranoid, it is probably a good idea because the data won't be written to disk. If you are incredibly, extremely, hyper-paranoid, it is not a good idea because it can be intercepted using Van Eck phreaking or screen-watching. And if you're at a level of paranoia beyond that - well, stay away from computers.

Encrypting With Passphrases Instead of Keys

Sometimes dealing with public and private keys to encrypt a file is just a big hassle. Perhaps the other person has not created a public key; or perhaps they shared it with you, but you can't entirely trust their public key because a man in the middle could have changed it to their own key (thus allowing them to decrypt files that you think can only be decrypted by the intended recipient).

It may be advantageous, in these cases, to have a method of encrypting files that does not use public keys. This is where a handy feature called "symmetric encryption" can be used.

Symmetric encryption uses a strong cipher, called CAST5 (see #References), to encrypt a file using a passphrase, rather than a public/private key pair. As with any passphrase-protected encryption, the passphrase is the weakest link in the process, and only a very strong passphrase can give you the confidence of a strongly-encrypted file.

Keep in mind that this is not as ideal as encryption using keys, but is more convenient (security and convenience are on opposite sides of the same scale).

This can be done in gpg using the -c or --symmetric command line options:

$ gpg -c filename
Enter passphrase:<YOUR-PASSWORD>
Repeat passphrase:<YOUR-PASSWORD>

The result of this command is a binary file, filename.gpg.

To make an armored ascii output file (if you're wondering what an ASCII armored file is, visit http://en.wikipedia.org/wiki/Binary-to-text_encoding), use the --armor option:

$ gpg --symmetric --armor filename
Enter passphrase:<YOUR-PASSWORD>
Repeat passphrase:<YOUR-PASSWORD>

The result of this command is an ascii file filename.asc.

To decrypt the gpg file:

$ gpg filename.gpg
gpg: CAST5 encrypted data
Enter passphrase:<YOUR-PASSWORD>

WARNING: This will print the contents of your file to standard output. You definitely don't want that to happen. Instead, use the -o or --output flags to dump the decrypted contents to a file:

$ gpg filename.gpg --output decrypted_filename.txt
gpg: CAST5 encrypted data
Enter passphrase:<YOUR-PASSWORD>

Similarly, for the armored ascii file, use the -d or --decrypt command-line option:

$ gpg -d filename.asc --output decrypted_filename.txt
gpg: CAST5 encrypted data
Enter passphrase:<YOUR-PASSWORD>

What to do with the original file after you encrypt it?

One of the things that must be addressed is the issue of what to do with the original file once it has been encrypted. It's important to securely delete it, if it merits encryption.

There are several utilities available to do this; these include:

  • rm -P - overwrites files 3 times (available on Mac)
  • shred - securely deletes files (Unix only)
  • fwipe - alternative to shred, overwrites file 5 times (available on Unix or on Mac via Fink)

Signing Files

Hashing Files

This is the "poor-man's" quick way to sign a file. A hash is a one-way algorithm, difficult to reverse-engineer, that can be used to digest a large amount of information into a small/fixed number of bits. See Hash function (wikipedia) for details.

There are a large number of hash algorithms available in GPG; these are:

  • MD5
  • SHA1
  • RIPEMD160
  • SHA256
  • SHA384
  • SHA512
  • SHA224

To hash a string on the command line, use the following command:

$ echo "This is the string that will be hashed." | gpg --print-md MD5
5E 3D 07 8C 07 07 97 09  C8 52 9C 76 C5 DC 3C BF

$ echo "This is the string that will be hashed." | gpg --print-md SHA1
013E 1D79 19C3 3DDA 0830  D2A4 C346 BD62 ECC8 1A16

$ echo "This is the string that will be hashed." | gpg --print-md SHA256
6062F9DA B80754B4 CEF9327B ABC813EC 956A6CF8 6C5D4522 770AF540 92B465F2

Next, comparing hashes of very similar data:

$ echo "This is the string that will be hashed." | gpg --print-md SHA512
C5418750 FDE2E24F 1CD52E76 5662023F 7384D706 B36F8E93 59F24D28 158968E3 003F34E0
 DC034261 6D479FBE 5E56BCF3 70916B4C 27844A99 FD7C2EF6 DCAAFD90

echo "This is the string that will be hashed\!" | gpg --print-md SHA512
C111B315 271989B5 8683FD72 320B47FA C6FFBE8C 08763629 D6E9AEBB 4F76320B 0649ED45
 F85011AC DFA8898E 3A5E0361 E9AB35CD FCE137AA 989D91CD 5408C525

Even a small change in the original string or data will lead to a completely different hash, which is one of the strengths of a hash. If a file is changed or corrupted in even a very minor way, the hash will be completely different. If a hash is not long enough, this strength can be overcome using a Birthday Attack (see Birthday Attack (wikipedia)).

NOTE: don't use MD5 hashes, they are vulnerable to the birthday attack. SHA256 and SHA512 are good choices, since both are SHA-2 algorithms, which are stronger than the SHA-1 algorithm (see the Wikipedia articles for these for more info).

To hash a file on the command line, use the following command:

$ cat file
This is the file that will be hashed.

$ cat file | gpg --print-md SHA512
9CDE290F 65062013 C9AD3164 F1D1687B 8670C9C5 BFA510B2 F49EE882 E2CF6318 8DD0FD74
 09EDEB57 167179E4 D9E0F826 26ED58B9 56A9B79A 88BC8F25 9A770AB6

To eliminate the spaces from the hashes, you can use a little sed one-liner:

$ echo "This is the string that was hashed." | gpg --print-md SHA512
39F1083B 3D6C5522 301CCEFA DD2578EA A453DBFD F344CB1F 8221CE5F BC596840 3CF987FB
 21F26D8E 27EBCD0E EAA7D841 9C96437C BF080904 96DBE81B 5A04F944

$ echo "This is the string that was hashed." | gpg --print-md SHA512 | sed -E -e :a -e '$!N; s/\n/ /g; ta' | sed 's/ *//g'
B57DF60A4BBD1797433EF2EC184F06E18442B23B03E19261434B649D29757434D70ECB34243C1FFD0F88F6821485C424D01B10841A90ADC74BC1D62DACEEC0C7

That first sed trick is thanks to [1]. It's difficult to do with sed because sed isn't very graceful at handling multi-line stuff; it's mainly built to operate on text on a line-by-line basis.

You can do it a lot easier with Perl:

$ echo "This is the string that was hashed." | gpg --print-md SHA512 | perl -p -e 's/\n//;s/ *//g'
B57DF60A4BBD1797433EF2EC184F06E18442B23B03E19261434B649D29757434D70ECB34243C1FFD0F88F6821485C424D01B10841A90ADC74BC1D62DACEEC0C7

GPG Signatures of Files

Sometimes it is desirable to create a signature for a particular file that is made publicly available for download. This is the case if, say, you're worried that a software project's "latest version" was actually maliciously tampered with by a third party, or that somebody might have hacked a site and injected malware into all the downloads.

An individual can use their private key to sign a file, and create a "detached signature" - i.e. a signature in an external file. Then anyone with their public key can then verify the file using its signature.

Creating a Detached Signature

To sign a tarball file.tar.gz:

gpg --armor --detach-sign file.tar.gz

This creates a signature file, file.tar.gz.asc.

Take a moment to consider why this works: the original author uses a private key to sign a file; that signature can then be combined with their public key to verify that yes, in fact, the file you have was precisely the file they signed.

If someone tampers with file.tar.gz, it will change the resulting signature. This will result in an invalid signature file.

However, here's the key: even though someone who could tamper with file.tar.gz could also tamper with the signature file, there is NO WAY for an attacker to generate a signature file for the tampered-with file.tar.gz file that would be VALID when combined with the original author's public key, unless the attacker had their private key. Which is much harder than getting access to a web server to tamper with a download file.

The result is that any tampering with file.tar.gz, even the slightest change, will be evident in a failed/mismatched signature. And the real strength of the signature method is that a new signature is impossible to create without the private key. So being able to tamper with the signature file does not help an attacker, because they aren't able to generate a valid signature file without the original author's private key.

Verifying Using a Signature

To verify file.tar.gz using file.tar.gz.asc:

$ gpg --verify file.tar.gz.asc file.tar.gz

To do this, you'll need the public key of the person who created the signature. See #Obtaining Public Keys from Public Key Server above. Typically, software projects that provide a detached GPG signature (the GPG signature for a file tarball-x.y.z.tar.gz will be tarball-x.y.z.tar.gz.asc or tarball-x.y.z.tar.gz.sig) will also provide a list of software developers who might have signed the release. You can run the command

$ gpg --search-keys 'Developer Name'

to find their public key from a public server. Note that unless you have indicated that you trust the key, or that someone else whose key you trust trusts this key, you'll get a warning when you verify the signature that looks like this:

$ gpg --verify mailman-2.1.14-1.tgz.asc mailman-2.1.14-1.tgz
gpg: Signature made Tue Mar  1 13:37:09 2011 MST using DSA key ID 953B8693
gpg: Good signature from "Mark Sapiro <mark@msapiro.net>"
gpg:                 aka "Mark Sapiro (MAS) <msapiro@value.net>"
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: C638 CAEF 0AC2 1563 736B  5A22 555B 975E 953B 8693

The recommended method is to use a key server, NOT to download the public key from the website, because if someone can tamper with a file provided for download they can also tamper with a public key provided for download, and if they provide you with a malicious public key, a malicious download, and a malicious file signature, the file will still be verified).

References

GPG Quick Start:

GPG Documentation: CAST5 (used in symmetric encryption):

GPG at the "Security Viewpoints" blog:

MacWorld discussion of secure deletion of files: