PGP

From HerzbubeWiki
Jump to: navigation, search

About

This page talks about PGP, Pretty Good Privacy, the concepts behind the technology and how to use one of its implementations, the free Gnu Privacy Guard (GnuPG, or even shorter GPG).

On a related page there is more information on how to handle keysigning party stuff. The MyPGP page has information about the actual PGP key that I use.


References

The GNU Privacy Handbook (very good primer!) 
http://www.gnupg.org/gph/en/manual.html
GnuPG (2.0) manual 
http://www.gnupg.org/documentation/manuals/gnupg/
Various HOWTOs 
http://www.gnupg.org/documentation/howtos.en.html
Mac GPG website 
http://macgpg.sourceforge.net/
OpenPGP standard 
http://www.ietf.org/rfc/rfc2440.txt
Information about keyservers (including a list of them) 
http://www.rossde.com/PGP/pgp_keyserv.html
PGP packet visualizer (displays parts of an ASCII-armored PGP key)
http://www.pgpdump.net/
The Keysigning Party HOWTO 
http://www.cryptnet.net/fdp/crypto/keysigning_party/en/keysigning_party.html (includes valuable and well formulated thoughts about "signing role keys and pseudonymous keys" and "when your key expires")
Biglumber (key signing coordination) 
http://biglumber.com/x/web


Glossary

Keypair 
A pair of keys consisting of a private key and a public key
Private key 
The part of a key that is to be kept secret. Used for decrypting and signing.
Public key 
The part of a key that can be given to anyone. Used for encrypting and verifying signatures.
Keyring 
A collection of keys. A public keyring contains public keys, a private keyring contains private keys.
DSA 
Digital Signature Algorithm, a standard for digital signatures. For details see the Wikipedia article.
ElGamal 
An asymmetric key encryption algorithm. For details see the Wikipedia article.
Key length 
Measured in bits. The longer a key the more secure it is against brute-force attacks. With longer keys, encryption and decryption are slower and the length of signatures may also be affected.
User ID 
Associates a key with a real person. The User ID consists of Real Name, Comment and Email Address in this form "Heinrich Heine (Der Dichter) <heinrichh@duesseldorf.de>". Any number of User IDs may be attached to a key, to allow the key to be used in different roles (e.g. as an employee at work and as a private person).
Passphrase 
A password, often in the form of an entire phrase or sentence, used to protect a private key.
Revocation certificate 
A revocation certificate is generated from a private key and revokes the associated public key. The certificate is published to notify others that the public key should no longer be used for encryption or verifying signatures, e.g. because the private key has been compromised. A revoked public key can still be used to verify signatures made in the past.
Signature 
Usually refers to a document signature. A document signature certifies and timestamps a document. If the document is subsequently modified in any way, a verification of the signature will fail. A document signature is the result of applying a hash function to the document.
Clearsigning 
Generate a signature for a document and append the signature below the original document, which is retained in clear text.
Key signature 
When a public key (or more accurately: one or more of the key's user IDs) is signed by another key.
Certificate 
Another term for "key signature"; this is sometimes used to distinguish key signatures from document signatures.
Self-signature 
When the components of a public key are signed with the corresponding private master signing key.
Symmetric cipher 
A symmetric cipher is a cipher that uses the same key for both encryption and decryption. Two parties communicating using a symmetric cipher must agree on the key beforehand. Modern examples of symmetric ciphers include 3DES, Blowfish, and IDEA.
Public-key cipher 
A cipher that uses a public key for encryption, and a private key for decryption. Public-key ciphers are based on one-way trapdoor functions.
Hybrid cipher system 
A system where a message is encrypted with a symmetric cipher key, and that key is then encrypted using a public-key cipher. Both the encrypted message and symmetric key cipher can then be transmitted to the communicating party in one package. The symmetric cipher key changes with each message, hence it is sometimes called a session key.
Web of trust 
A mechanism where someone does not have to validate all of his or her correspondents' public keys personally, but instead relies on other, trustworthy people having done so before. If A trusts B, and B has validated and signed C's public key, A can implicitly trust C's signed public key
Trust level 
Instead of having just 2 options, "trust" and "no trust", correspondents can be assigned a trust level that, together with some rules of evaluating these levels, can be used to make the web of trust more flexible.


Concepts

Key creation

The basic requirement when creating a new keypair is to generate one public and one private key. GnuPG goes beyond this, as the "GNU Privacy Handbook" states:

GnuPG uses a [somewhat more] sophisticated scheme in which a user has a primary keypair and then zero or more additional subordinate keypairs. The primary and subordinate keypairs are bundled to facilitate key management and the bundle can often be considered simply as one keypair.

The default when creating a new key with GnuPG is to create

  • a DSA keypair as the primary keypair, which is usable only for making signatures
  • an ElGamal subordinate keypair, which is usable for encryption only

GnuPG only knows these types of keys:

  • DSA (for signatures)
  • ElGamal (for encryption only)
  • ElGamal (for both encryption and signatures)


Key elements

A public key consists of

  • the public portion of the master key (by default a sign-only DSA key)
  • the public portions of the subordinate signing and/or encryption subkeys (by default an encrypt-only ElGamal key)
  • a set of user IDs, attached to the master key, used to associate the public key with a real person

The structure of a private key is similar to that of a public key, except that it contains only the private portions of the keys, and there is no user ID information.

Any signing or encryption key (whether it is a master or a subordinate key) has the following attributes:

  • ID
  • when it was created
  • when it will expire
  • etc

A user ID has the following attributes

  • the name of the real person it identifies
  • an optional comment
  • an email address


Key validation

After you add the public key of another person to your public keyring, you want to validate it so that you know that the key is genuine and can be trusted. This is done in the following way

  • extract the key's fingerprint
  • verify with the key's owner that the fingerprint is correct; this can be done in any way (e.g. meet the owner in person, contact him or her over the phone or by email, look at the owner's website etc.) as long as you can guarantee that you are communicating with the key's true owner
  • validate the other person's key, thereby giving it trust, by signing it with your own key


Document signatures

Generating a signature from a document using a hash function, and then sending both the document and the signature in clear text, is worthless. An attacker could take the document, change it, generate a new signature from the changed document and simply send the new document/signature pair without the recipient noticing any manipulation.

Encrypting the document but not the signature does not help solve the problem - an attacker could change the signature, thus provoking a signature verification to fail even though the document is still intact.

Encrypting the signature is the solution: The signature is now safe from tampering, and if the document is changed by an attacker, signature verification will fail - which is exactly what is intended.

Encrypting the document as well is optional, depending on whether the document is public or private.

What keeps an attacker from modifying a public document (or substituting an encrypted private document with an entirely new document), generating and encrypting a new signature and then sending the new document/signature pair instead of the old pair? Obviously signature-encryption must be done using a secret that only the signing party can know. What happens is that signature-encryption is done using the signer's private key, while anybody can verify (=decrypt) the signature using the signer's public key.


Key management

Although public keys do not need to be protected per-se, it is still extremely important to know whether or not a public key genuinely belongs to the person in question. A fake public key could be used to mount a man-in-the-middle attack: Attacker X generates his own public/private keypair, then replaces person B's public key with his own public key. Person A will now unwittingly use the attacker's public key to encrypt a message, X will be able to decrypt and read the message, after which he re-encrypts the message using B's true public key and forwards the message to B, without the recipient noticing anything.

From the "GNU Privacy Handbook":

Good key management is crucial in order to ensure not just the integrity of your keyrings but the integrity of other users' keyrings as well. The core of key management in GnuPG is the notion of signing keys. Key signing has two main purposes: it permits you to detect tampering on your keyring, and it allows you to certify that a key truly belongs to the person named by a user ID on the key.

The first thing that needs to be done to protect the public key of your own keypair from tampering is: self-sign it. GnuPG does this automatically for you when it generates the key.

The next step is to personally validate public keys of other people. This usually involves a personal meeting and an identity check. As a result of validation, you sign the public keys of those people who have passed validation.

The final step, for those correspondents whose keys you are unable to personally validate, is the so-called "Web of trust", where you implicitly trust public keys of people you do not know, but whose public keys have been validated/signed by people you do know and/or trust. By assigning a trust level to public keys in your keyring, the web of trust becomes flexible. The following trust levels exist (copied verbatim from the "GNU Privacy Handbook"):

unknown 
Nothing is known about the owner's judgment in key signing. Keys on your public keyring that you do not own initially have this trust level.
none 
The owner is known to improperly sign other keys.
marginal 
The owner understands the implications of key signing and properly validates keys before signing them.
full 
The owner has an excellent understanding of key signing, and his signature on a key would be as good as your own.


Key signatures

Key signatures are sometimes also known as "certificates". According to RFC 2440:

  • User IDs are signed, not keys (10.1)
  • User IDs are attached to the master key, not any of the subkeys (10.1), therefore it can be said that the master key accumulates signatures by other people
  • One of the key's user IDs can be designated as the key's primary user ID (5.2.3.18). In GnuPG, to change a key's primary user ID, start an interactive GnuPG session using --edit-key, then select the desired user id (command uid) and make it the new primary user ID (command "primary")
  • A signature can be made using a specific user ID (5.2.3.21), which allows to define a user ID on a key that exists only for the purpose of signing other keys, while other user IDs can server other roles. I have not yet found out how to specify to GnuPG which user ID it should explicitly use. Currently it seems that GnuPG simply makes the signature without any specific user ID. This theory is supported by the following experiment:
    • Display a signature you have made with a key that has 2 or more user IDs
    • GnuPG will tell you that the signature was made using the key's current primary user ID
    • Change the key's primary user ID and re-display the signature
    • GnuPG will tell you that signature was made using the new primary user ID
    • Self-signatures will also be displayed as having been made by whichever is the current primary user ID
  • An URL may be attached to a signature which points to a documents that describes the policy that the signature was issued under (5.2.3.19). This URL may be specified to GnuPG using the --cert-policy-url option


Anatomy of a key

Why is there a need to have different keys for signing and encrypting?

  • Because these are different activities, therefore it makes sense to have different keys for these activities
  • For instance, you may want the keys to have different lifetimes
  • Typically, a digital signature has a long lifetime, e.g. forever, therefore a signing key should also not expire
  • On the other hand, it may make sense to change the encryption key periodically for extra security

Why is the primary key a sign-only key?

  • Because it collects the signatures of others who have confirmed your identity
  • This allows the encryption key to be a subkey that can be changed periodically

Why is there only one encryption subkey?

  • There is no additional security gained by having two or more active encryption subkeys
  • Also, you can't force people sending you encrypted mail using a specific subkey
  • There may of course be any number of expired encryption subkeys on a keyring so that documents encrypted in the past may still be decrypted, but only one subkey needs to be active at any given time

Why do keys not have an expiry date?

  • Mainly for convenience
  • One reason why an expiry date might make sense is if the key is being used for an event such as a political campaign and will no longer be useful after the campaign is
  • Another reason might be to protect the key from abuse if you lose control of it, and if you do not have a revocation certificate with which to revoke the key. Having an expiration date on the key ensures that it will eventually fall into disuse.


Using GnuPG on the command line

Configuring the shell

Possibly for GnuPG 2 only, the following lines probably need to be added to .bashrc, or whatever initialization file is used for shell invocations:

GPG_TTY=$(tty)
export GPG_TTY

The environment variable GPG_TTY is required so that GnuPG is capable of obtaining a pass phrase from the user. Without this, a command line such as

echo "test" | gpg --clearsign

will fail with this rather cryptic message:

Inappropriate ioctl for device

Recommendation from the GnuPG website. Tested that this works on macOS for the Homebrew-installed GnuPG.


Creating a key

Use the following command to start generating a new key:

gpg --gen-key

Provide the following answers in the ensuing interactive session:

  • Kind of key = DSA and ElGamal (the default is fine for me since I don't understand anything about cryptography)
  • Keysize = 2048 (1024 would also be fine according to the "GNU Privace Handbook", but I prefer to use the maximum of 2048 just to be on the safe side)
  • Key is valid for = key does not expire
  • User ID = Patrick Näf Moser <herzbube@herzbube.ch>
  • Passphrase = secret

The newly generated keypair is stored in the key database (consisting of several files) located under

~/.gnupg/

The public key of the newly generated keypair is automatically self-signed using the private key. When new sub-keys or user IDs are later added to the key, they will also be automatically self-signed.


Generating a revocation certificate

The following command generates a revocation certificate in ASCII-armored format, writing the certificate into a file

gpg --output herzbube@herzbube.ch-90D8DB38.asc --gen-revoke 90D8DB38

A revocation certificate should be generated immediately after a new key has been generated, so that the key can be revoked later on in case it is lost or the passphrase is forgotten.


Listing keys

List all available keys:

tharbad:~ --> gpg --list-keys
/Users/patrick/.gnupg/pubring.gpg
---------------------------------
pub   1024D/DF363896 2002-12-14 [widerrufen: 2009-08-23]
uid                  Patrick Näf <herzbube@herzbube.ch>

pub   1024D/90D8DB38 2006-04-30
uid                  Patrick Näf Moser <herzbube@herzbube.ch>
sub   2048g/E0BCA6C0 2006-04-30

pub   1024D/65D0FD58 2003-07-11 [verfällt: 2033-07-03]
uid                  CA Cert Signing Authority (Root CA) <gpg@cacert.org>
sub   2048g/113ED0F2 2003-07-11 [verfällt: 2033-07-03]


List a single key with fingerprint and signatures:

gpg --fingerprint --list-sigs 90D8DB38


Deleting keys

Deleting either a public key only, or deleting both the public and the private key, works like this:

gpg --delete-key 90D8DB38
gpg --delete-secret-and-public-key 90D8DB38

Note: Since the private key is not decrypted, no passphrase is required.


Examining and manipulating keys

Keys can be examined in detail and manipulated by the following command:

gpg --edit-key 90D8DB38

This will start an interactive shell, where - among others - the following useful commands are available:

help 
print a list with commands
toggle 
switch between the public and private portions of a key
check 
list signatures of user IDs
fpr 
display the key's fingerprint
passwd 
change passphrase
addkey/delkey/revkey 
add/delete/revoke a key
adduid/deluid 
add/delete a user ID (to revoke a user ID, its self-signature must be revoked using revsig)
sign/revsig 
sign/revoke signature
expire 
update a key's expiration date
trust 
modify a key's trust level
showphoto 
display a photo user ID

The following has been copied verbatim from the "GnuPG Privacy Handbook":

chloe% gpg --edit-key chloe@cyb.org
Secret key is available.

pub  1024D/26B6AAE1  created: 1999-06-15 expires: never      trust: -/u
sub  2048g/0CF8CB7A  created: 1999-06-15 expires: never
sub  1792G/08224617  created: 1999-06-15 expires: 2002-06-14
sub   960D/B1F423E7  created: 1999-06-15 expires: 2002-06-14
(1)  Chloe (Jester) <chloe@cyb.org>
(2)  Chloe (Plebian) <chloe@tel.net>
Command> toggle

sec  1024D/26B6AAE1  created: 1999-06-15 expires: never
sbb  2048g/0CF8CB7A  created: 1999-06-15 expires: never
sbb  1792G/08224617  created: 1999-06-15 expires: 2002-06-14
sbb   960D/B1F423E7  created: 1999-06-15 expires: 2002-06-14
(1)  Chloe (Jester) <chloe@cyb.org>
(2)  Chloe (Plebian) <chloe@tel.net>

The first column indicates the type of the key:

pub 
identifies the public master signing key
sub 
identifies a public subordinate key
sec 
identifies the private master signing key
sbb 
identifies the private subordinates keys

The second column indicates the key's bit length, type, and ID. Possible key types are:

DSA key
encryption-only ElGamal key
ElGamal key that may be used for both encryption and signing
RSA key (regardless of whether it is an encryption-only key, or may be used for both encryption and signing)

The creation date and expiration date are given in columns three and four. The user IDs are listed following the keys.

Note: User IDs are associated with the public key. When looking at the private key components, user IDs are listed for convenience only - not because they belong to the private key.


Encrypting

Encrypt a file:

gpg --output /tmp/foo.txt.gpg --recipient E0BCA6C0 --encrypt /tmp/foo.txt

GnuGP needs to identify the recipient by some means. The man page says that one of the following things can be used:

  1. The key ID
  2. The key fingerprint (obtained when keys are listed using the --fingerprint option)
  3. A substring (what exactly the substring is matched against is not clear). By trial and error, I have seen that I can use both the main key ID and the sub key ID. I can also use my name in a substring match, e.g. "Patrick Näf", in which case GnuPG will find the first name in the list that matches, which happens to be my most recent key.

For a reason as yet unknown to me, GnuPG then always asks for confirmation (the complaint is this: "There is no assurance this key belongs to the named user"), after which the file will be encrypted and written to the file specified using the --output argument (if the argument is omitted, output is written to a file with the same name as the original file, but with extension .gpg appended).


To encrypt a file with a symmetric ciper, i.e. without using public-key cryptography:

gpg --output /tmp/foo.txt.gpg --encrypt /tmp/foo.txt --symmetric

The cipher used by default, as per the GnuPG man page, is the CAST5 algorithm, but it may be changed by providing the --cipher-algo option.


Decrypting

Decrypt a file:

gpg --output /tmp/foo.txt --decrypt /tmp/foo.txt.gpg

GnuPG will nicely detect which key is the correct key to decrypt the file. If the key is protected by a pass phrase, GnuGP will then ask you for the pass phrase. If the correct pass phrase is entered, the file will be decrypted and written to the file specified using the --output argument (stdout if the argument is omitted).


Signing

Documents

Sign a file:

gpg --default-key 90D8DB38 --output /tmp/foo.sig --detach-sign /tmp/foo.txt

The signature is made with the key specified by the --default-key option. If this option is omitted, GnuPG automatically selects the first private key it encounters in its private keyring. Finally, the default key may be permanently defined by adding the following option to GnuPG's preferences file (by default ~/.gnupg/gpg.conf):

default-key 90D8DB38

Note that in the above example, a so-called detached signature is made, i.e. the signature stored in foo.sig is detached from the dcument that it belongs to (foo.txt). To store the document and its signature in the same output file, use the --sign instead of the --detach-sign option.

To retain the original document in clear-text, while attaching the signature below the document, use clearsigning:

gpg --output /tmp/foo.sig --clearsign /tmp/foo.txt

This is commonly used to sign emails or usenet/forum postings.


Keys/User IDs

Sign all user IDs of a key (the certificate check level can be specified interactively) with your default key, attaching the given policy URL to the signature:

gpg --ask-cert-level --cert-policy-url http://herzbube.ch/pgp-key-signing-policy.html --sign-key B7947C81

Sign all user IDs of a key with the non-default key 12345678:

gpg -u 12345678 --ask-cert-level --sign-key B7947C81

To sign only specific user IDs of a key, start an interactive session to select the user IDs (command uid <n>), then sign them (command sign):

gpg --ask-cert-level --edit-key B7947C81

To list all signatures on a key:

gpg --list-sigs B7947C81

For each signature listed, there are several flags in between the sig tag and the key ID. These flags give additional information about each signature. From left to right, they are

  • the numbers 1-3 for certificate check level; no number indicates certificate check level 0 (see --ask-cert-level)
  • "L" for a local or non-exportable signature (see --lsign-key)
  • "R" for a nonRevocable signature (see the --edit-key command "nrsign")
  • "P" for a signature that contains a policy URL (see --cert-policy-url)
  • "N" for a signature that contains a notation (see --cert-notation)
  • "X" for an eXpired signature (see --ask-cert-expire)
  • the numbers 1-9 or "T" for 10 and above to indicate trust signature levels (see the --edit-key command "tsign")


Verifying a signature

Verify a detached signature:

gpg --verify /tmp/foo.sig /tmp/foo.txt

Verify a signed document (whether it is clearsigned or not):

gpg --verify /tmp/foo.sig

Verify and decrypt a signed document:

gpg --output /tmp/foo.txt --decrypt /tmp/foo.sig


Exporting a key (public and/or private)

The following command exports a public key, writing it into a file in ASCII-armored format:

gpg --armor --output herzbube@herzbube.ch-90D8DB38.asc --export 90D8DB38

Note: All parts of the public key are exported, i.e. master and subordinate keys as well as the user IDs and any signatures.


The following command works similarly, but exports the private instead of the public key. Note: The passphrase is not removed by this!

gpg --armor --output herzbube@herzbube.ch-90D8DB38.private.asc --export-secret-keys 90D8DB38


Importing and validating a public key

The following command imports a public key into the user's public keyring:

gpg --import foo.gpg

If the key is already present in the keyring, the keyring components are merged with the components imported from the file.

To validate the key start an interactive edit session where you first list the key's fingerprint to verify it, then sign the key to validate it, and finally list the key's signatures to check that your signature has been added correctly:

gpg --edit-key foo@bar.org
[...]
Command> fpr
[...]
             Fingerprint: 268F 448F CCD7 AF34 183E  52D8 9BDE 1A08 9E98 BC16
[...]
Command> sign
[...]
Command> check
[...]


Adding/deleting vs. revoking key components

Both new subkeys and new user IDs may be added to your keypair after it has been created, using the adduid and addkey commands in an interactive GnuPG shell. When a subkey or user ID is generated it is self-signed using your master signing key, which is why you must supply your passphrase when the key is generated.

Subkeys and user IDs may also be deleted. To delete a subkey or user ID you must first select it using the key or uid commands respectively, then you can delete the selected component using the delkey or deluid commands. Subkeys are deleted from both your public and private keys, while user IDs need to be deleted only from the public key.

Note: Deleting subkeys and user IDs is not really a good idea, because when other parties import the new public key into their keyring it will be merged with the old public key that is already present in the keyring - thus the deleted components are actually restored by the merge, making the delete operation useless. It is better to revoke subkeys and user IDs that are no longer to be used. Revocation also has the benefit that a public key retains some sort of history of what happened to its components.

Revocation for subkeys happens similar to deletion: First select the subkey with the key command, then issue the revkey command to revoke the key.

Revocation for user IDs is another matter: Because the OpenPGP specification does not support user ID revocation, a user ID cannot be revoked directly. Instead, its self-signature must be revoked; well-behaved correspondents will then stop to trust this user ID since it is now no longer protected from forgery by a signature. By removing all trust from it, the user ID has thus been effectively disabled.


Setting a key's trust level

The following command starts an interactive session that lets you modify a public key's trust level:

gpg --edit-key blake

The command trust can then be used to choose between several trust levels:

  • Don't know
  • I do NOT trust
  • I trust marginally
  • I trust fully

A key initially has the "Don't know" trust level. Trust levels are completely private, they are not packaged together with a key if it is exported. GnuPG's trust database is stored in this file:

~/.gnupg/trustdb.gpg

For each key, GnuPG displays a pair of trust levels, e.g.

pub  1024D/8B927C8A  created: 1999-07-02 expires: never      trust: m/f

In this example, the owner of the key is trusted marginally (m), while the key itself is trusted fully (f). The difference stems from the fact that the owner of the keyring has signed the key himself, which means he exactly knows that this key is valid, while other keys that may have been signed by the owner of the key can be trusted only marginally.


Keyservers

Keys can be exported to or imported from keyservers on the net. The following commands can be useful:

gpg --keyserver subkeys.pgp.net --recv-key 0xBB7576AC
gpg --keyserver subkeys.pgp.net --send-key 0xBB7576AC

The Wikipedia article on keyservers lists some interesting starting points. Major keyservers are said to synchronize themselves, so it should be ok to pick any one of those.

As an interesting historic side note: It seems that older keyservers have been unable to handle keys with multiple subkeys. To distinguish newer keyservers that are able to handle this type of key, these newer servers have been named subkeys.pgp.net.


Generating a message digest

Print message digests for all known algorithms:

gpg --print-mds foo.txt

Print message digest for MD5 algorithm:

gpg --print-md md5 foo.txt

Algorithms known to GnuPG on my Mac at the time of writing:

  • md5
  • sha1
  • rmd160
  • sha224
  • sha256
  • sha384
  • sha512


GnuPG on the Mac

Installing GnuPG

GnuPG from the Mac GPG site

Probably the easiest solution to get GnuPG is to install the package provided on the Mac GPG website. Choose the package that is suitable for your Mac OS X version, then install the .mpkg while logged in as an administrator.

The package will install files into these directories:

/usr/local/bin
/usr/local/lib
/usr/local/libexec
/usr/local/share

The following binaries are provided (in /usr/local/bin):

gpg
gpg-zip
gpgsplit
gpgv


fink

As an alternative, GnuPG can also be installed through the fink package manager. If you install the gpg package, the resulting binaries are installed in

/sw/bin

(unless you installed fink itself into a non-standard directory, i.e. somewhere else than /sw).

Unfortunately, the programs available on the Mac GPG website expect that the gpg binary is located in /usr/local/bin. You will first encounter the problem when you install GPGPreferences. The preference pane detects that gpg is missing in the expected location and helpfully offers to create a symbolic link in /usr/local/bin (or to copy the file, but you should not do that...). On my machine, however, this did not work for some reason (I filed a bug report on sf.net, so far I had no response), and I had to manually create the symbolic link:

sudo ln -s /sw/bin/gpg /usr/local/bin/gpg

When I wrote this, GPGPreferences was at version 1.2.2, maybe later versions will have the symlink bug fixed...


Using GnuPG

Overview

Once gpg has been installed for the command line, there are various GUI tools that make use of it. This chapter has notes about some of them.


Mac GPG

Mac GPG is an entire little suite of GUI tools:

  • GPGPreferences is used to manage the GnuPG configuration located in your home directory:
~/.gnupg/gpg.conf
  • GPG Keychain Access is used to actually manage your public an private keys in these files:
~/.gnupg/pubring.gpg
~/.gnupg/secring.gpg
  • GPGFileTool helps you to quickly decrypt and encrypt files.
  • GPGDropThing is supposed to "quickly use GnuPG on text via GUI" (from the Mac GPG website), but the tool somehow never worked for me, so I don't really know what exactly it's all about...


Ggp Tools

Source

http://www.tomsci.com/gpgtools/

This Mac OS X tool encrypts/decrypts and signs/verifies files and clipboard content. I use it as a replacement for GPGFileTool because it covers my use case much better than GPGFileTool.

My use case is this:

  • open a .pgp file from a Finder window
  • enter my passphrase
  • the application automatically drops the decrypted file into the same folder where the original file is located
  • I can quickly open the decrypted file from the same Finder window that is already open (see step 1)

Gpg Tools does exactly that, so I am happy.


A little rant about GPGFileTool, the competing program from the Mac GPG tool suite: GPGFileTool has the annoying habit that it displays a file dialog after I enter the passphrase. Mistake #1: By showing the file dialog to me, the program kind of asks me to confirm the action that I already know I want to perform: decrypt a file. Mistake #2 (and this is worse): The file dialog always points to the Documents folder in my home directory. This practically forces me to save the decrypted file to the Documents folder, because it is simply impractical to navigate in the file dialog to the location from where I opened the original file. To get at the decrypted file, I then have to navigate in the Finder to my Documents folder. At least here I can simplify the task by using some sort of shortcut (usually the default shortcut displayed by the Finder in the sidebar of its windows). This may sound as if I'm quibbling, but in the end it is the "small" things that count. Look at it this way: with Gpg Tools I have 3 steps of interaction, with GPGFileTools I have 5.


gpg-agent

The purpose of gpg-agent is to cache the passphrase for decrypting a secret key in memory for a while, so that the user does not have to enter the passphrase every time she wants to access the secret key. The idea has some similarities to ssh-agent, but in general it appears that gpg-agent is not as powerful as ssh-agent (esp. because it is not capable of forwarding any requests over the network).

Using gpg-agent on Mac OS X in a convenient manner needs some tricks that I have copied from this blog entry:

http://vafer.org/blog/20060805003530


The main problems to solve are these:

  • gpg-agent is intended to run as daemon. This can be achieved by way of a user-specific login item, or a system-wide login hook
  • Clients of gpg-agent expect to find an environment variable that will tell them which socket they can use to connect to the agent; normally this variable is set by gpg-agent when it is started and inherited by other processes. On Mac OS X this is a problem because it is difficult to make all processes of a user session inherit environment variables from a common parent process. The solution to the problem is to pre-define a socket file in the user's home directory and to setup a "static" environment variable whose content never changes
  • gpg-agent should be terminated when the user logs out.


First we start by installing the necessary packages through fink:

fink install gpg-agent pinentry


To make gpg-agent launch when the user logs in:

TODO (can we use launchd? if so gpg-agent should not daemonize itself)

Example login hook script:

#!/bin/sh
su -l $1 -c "/sw/bin/gpg-agent --daemon --use-standard-socket" > /Users/$1/.gnupg/.gpg-agent

To make the standard socket known to other processes, add the following variable to ~/.MacOSX/environment.plist (e.g. using the excellent RCEnvironment.prefPane)

GPG_AGENT_INFO = /Users/<username>/.gnupg/S.gpg-agent:4559:1


To make gpg-agent terminate when the user logs out:

TODO

Finally, configure gpg-agent by writing stuff into ~/.gnupg/gpg-agent.conf. Among other things, we define the path to the pinentry program:

pinentry-program /sw/bin/pinentry
no-grab
default-cache-ttl 1800


Final thoughts: On SourceForge there is a MacGPG2 project that promises to do everything for us, but it seems to be a not-very-transparent one-man show. Therefore I prefer to stick with GnuPG provided by Fink and my own configuration/setup.


GPGMail

GPGMail is a plugin/addon for Apple Mail. It currently works with versions of Apple Mail up to and including Mac OS X 10.5. Mac OS X 10.6 is currently not supported.

Website: http://www.sente.ch/software/GPGMail/English.lproj/GPGMail.html

Installation is superbly easy:

  • Download .dmg
  • Quit Apple Mail
  • From the .dmg, launch "Install GPGMail.app"
  • Start Apple Mail

Precondition for this to work is that the gpg binaries are located in one of the few expected locations. On my PPC Mac, everything worked out of the box when the binaries were installed in

/usr/local/bin


Configuration

gpg.conf

I usually add the following settings to my ~/.gnupg/gpg.conf:

default-key 90D8DB38
charset utf8
keyserver hkp://subkeys.pgp.net
keyserver-options auto-key-retrieve
utf8-strings
ask-cert-level
cert-policy-url http://herzbube.ch/pgp-key-signing-policy.html
list-options show-policy-urls
list-options show-keyserver-urls
list-options show-uid-validity


Web of trust

Currently I do not have any special web-of-trust settings.


HOWTOs

Use GnuPG to convert to/from ASCII armor

GnuPG also has the ability to convert any binary data into ASCII armored format, and back, using the command line options --enarmor and --dearmor. For instance:

gpg --enarmor </bin/cp >/tmp/cp.asc
gpg --dearmor </tmp/cp.asc >/tmp/cp.bin

A file armored in this way looks like this:

-----BEGIN PGP ARMORED FILE-----
Version: GnuPG v1.4.8 (Darwin)
Comment: Use "gpg --dearmor" for unpacking
[...]
-----END PGP ARMORED FILE-----


For what it's worth, this information can be used to extract the binary content of a PEM formatted file that has been generated by OpenSSL. If such a file contains an RSA private key, for instance, it would originally look like this:

-----BEGIN RSA PRIVATE KEY-----
[...]
-----END RSA PRIVATE KEY-----

We can now simply replace these header/footer lines by the corresponding header/footer lines displayed above for ASCII armored files, and GnuPG will happily decode the binary content of the file. In the above example, the RSA key would now have the DER format.

Note: The same conversion effect can also be achieved by using the openssl command line utility with its -inform and -outform options.


Use GnuPG to generate an RSA key that is usable for SSH authentication

The solution comes from the gnupg-users mailing list:

Assuming you want to add an RSA subkey to an existing PGP master key:

$ gpg --expert --edit-key 1234CDEF
[...]
addkey
[...]
Please select what kind of key you want:
   (2) DSA (sign only)
   (3) DSA (set your own capabilities)
   (4) Elgamal (encrypt only)
   (5) RSA (sign only)
   (6) RSA (encrypt only)
   (7) RSA (set your own capabilities)

Your selection? 7

Possible actions for a RSA key: Sign Certify Encrypt Authenticate
Current allowed actions: Sign Certify Encrypt

   (S) Toggle the sign capability
   (E) Toggle the encrypt capability
   (A) Toggle the authenticate capability
   (Q) Finished

Your selection? A

Possible actions for a RSA key: Sign Certify Encrypt Authenticate
Current allowed actions: Sign Certify Encrypt Authenticate

   (S) Toggle the sign capability
   (E) Toggle the encrypt capability
   (A) Toggle the authenticate capability
   (Q) Finished

Your selection? Q
RSA keys may be between 1024 and 4096 bits long.
What keysize do you want? (4096)
[...]


After generating the subkey in GnuPG, the problem remains how it can be converted for use with SSH. There is a utility named gpgkey2ssh which is part of GPG2, but this can convert only public PGP keys, so it is not really usable. The only way I have found so far requires the use of the utility openpgp2ssh that is part of the MonkeySphere project. The procedure works like this:

  • Export the public and private part of the key which contains the RSA subkey in question:
gpg --export 1234CDEF >1234CDEF.public.gpg
gpg --export-options export-reset-subkey-passwd --export-secret-subkeys 1234CDEF >1234CDEF.private.gpg
  • Notes:
    • It is not possible to export only the subkey, you will always get the entire key including the primary key and all subkeys. Because of this, you will have to enter a passphrase repeatedly, once for each subkey that is being exported/unprotected. If the subkeys have been generated in a regular way (i.e. using --edit-key and command addkey), the passphrase will be the same for all subkeys.
    • MonkeySphere can handle only the binary OpenPGP format, therefore the exported files must be in this format, not the ASCII armored format
    • MonkeySphere cannot handle passphrase protected private keys, therefore the private key must be exported without passphrase protection
  • If MonkeySphere is not yet installed, install it now. On a Debian system, this is done by installing the Debian package monkeysphere.
  • You should now have a command line utility named openpgp2ssh. Use it to convert the public/private parts of the RSA keys into a format that SSH can understand:
openpgp2ssh 9876ABCD <1234CDEF.public.gpg >9876ABCD.public.ssh
openpgp2ssh 9876ABCD <1234CDEF.private.gpg >9876ABCD.private.ssh
  • Notes:
    • openpgp2ssh requires the key ID (not the fingerprint) of the RSA subkey that it should convert (9876ABCD in the above example).


The final step is to install the converted key data on your local and remote machines so that it can be used by SSH:

  • Install the public key on the remote machine
cp 9876ABCD.public.ssh ~/.ssh/authorized_keys
  • Note: If the file authorized_keys already exists, you may wish to add the new key to the file instead of overwriting it
  • Install the private key on the local machine
cp 9876ABCD.private.ssh ~/.ssh/id_rsa
  • Note: The file id_rsa cannot contain more than one key. If you need different keys for different accounts/remote machines, each key must be placed in its own identity file. The correct identity file must then be selected using ssh's -i command line option, or the identity file must be specified on a per-host basis in SSH's configuration file ~/.ssh/config. See the OpenSSH page for details.
  • To protect the private key with a passphrase, you can use the following commands (uses the DES3 cipher for encryption):
openssl rsa -des3 -in ~/.ssh/id_rsa -out ~/.ssh/id_rsa.protected
mv ~/.ssh/id_rsa.protected ~/.ssh/id_rsa