Me:
  • Home
  • Finger Me
  • News:
  • Slashdot
  • Kuro5hin
  • Fark
  • Sluggy Freelance
  • Google:
    Current:
  • GPG/UPL Howto
  • TiVo Stuff
  • Old:
  • My MP3 Manager (M3)
  • Quick Tips for Using GPG

    $Revision: 1.5 $

    or
    UPL, PUBLIC SERVICE PAGE NO. 43 PARA 6. 'HOW NOT TO BE SEEN'

    This document is designed as a quick reference to get you up and running if you are at least somewhat familiar with mutt and PGP/gpg. If you are not (or are but have a few extra minutes free), I highly recommend reading this Howto. I don't go into as much detail as the author, and he provides some good overviews.

    OK, onto the action (index for the following steps)


    • Make sure GPG is installed and set up.
      1. Install GPG from your favorite software package or source (http://www.gnupg.org/)
      2. Read gpg --help|less. You don't need to remember which option does what, but you should be familiar with what options gpg provides from the command line, and the basic terminology it uses.
      3. Generate a keypair.
        1. gpg --gen-key
        2. 1 (DSA and ElGamal)
          1. 1024 or 2048 (My recommendation). As Neal Stephenson's Cryptonomicon put it, picking such a large key size (his was 4096) shows that you're either extremely optimistic about the future of computers or extremely cynical about some government's future allocation of computing resources. However, you only have to be slightly optimistic about the future of computers (or wait 6 months) to negate the speed hit of choosing a larger key size. For asymmetric or public key lengths, (cryptology expert) Bruce Schneier recommends 1280 bits through 2005 for individuals, 1536 for corporations, and 2048 for governments. That's just a few years away, so choose wisely.
          2. Choose an expiration period. This is useful if you forget your key; at worst, you will have to wait before people (should) stop trusting your key. This is up to you, but remember that you can always extend your certificate or revoke it (if you believe it was compromised), as long as you remember its passphrase.
          3. Enter your Name, email, and comment.
          4. Enter a passphrase. This is the MOST IMPORTANT step in the process. This is the only thing keeping someone who breaks into your box or otherwise obtains your private key from reading everything you've encrypted or posing as you, so it should be quite long and not based on any recognized algorithm (Natural language, etc). At the same time you must remember your passphrase to use your key, so it should be memorable. You can figure out how to come up with good passwords (L33T speak, foreign languages, first letters, etc), just make sure it's long enough to make brute force hard.
          5. Save a copy of your fingerprint offline. This is important - Print your fingerpring on paper! If someone hacks into your system, even without cracking your passphrase they could replace your key with theirs. If you really want to assert that "your" key yours, you need to be able make sure of this yourself.
            gpg --fingerprint "Your Name"
            I recomment keeping it with you somewhere; encrypted in your Palm Pilot, printed on a business card and kept in your wallet (along with the SSH/RSA fingerprints for hosts your login to frequently, but that's a separate matter).
      4. Change your options
        1. Find your KeyID with gpg --list-secret-keys
        2. Edit ~/.gnupg/options. I use the following:
          no-greeting
          default-key       
          encrypt-to         # Always encrypt to yourself so you # can decrypt it later
          escape-from-lines
          keyserver wwwkeys.us.pgp.net          # to lookup new keys by KeyID
          
    • Set up your mail client
      1. Setup procmail first
        1. Put the following in your .procmailrc to make older-skool PGP messages more readable:
          ##
          ## PGP
          ##
          :0
          * !^Content-Type: message/
          * !^Content-Type: multipart/
          * !^Content-Type: application/pgp
          {
                  :0 fBw
                  * ^-----BEGIN PGP MESSAGE-----
                  * ^-----END PGP MESSAGE-----
                  | formail \
                      -i "Content-Type: application/pgp; format=text; x-action=encrypt"
           
                  :0 fBw
                  * ^-----BEGIN PGP SIGNED MESSAGE-----
                  * ^-----BEGIN PGP SIGNATURE-----
                  * ^-----END PGP SIGNATURE-----
                  | formail \
                      -i "Content-Type: application/pgp; format=text; x-action=sign"
          }
          
      2. Mutt
        1. Mutt's default setup should contain most of the commands to correctly use gpg, but you still may want to change specific options. These are the following options in the UPL's global /etc/Muttrc that differ from the defaults (we find them useful).
        2. All mutt/pgp options, with descriptions
        3. In my own .muttrc, I have enabled the following options:
          set pgp_sign_as=""
          set pgp_replysignencrypted  # Sign replies on encrypted mail
          unset pgp_verify_sig    # ask me whether I want to check a pgp signature - think about this
          set pgp_timeout=7200    # forget PGP passphrase after 7200 seconds (=2 hours)
          set pgp_outlook_compat=no	# This corresponds to a mutt patch that
                                      # you'll need if you want to GPG communicate with outlook
          
          pgp-hook will@upl\\.cs\\.wisc\\.com 0xF4332B28	
          						# your .gnupg/options should take care of this...
          send-hook . \		# Default hook to use on send
              "set signature=~/.sig/default locale=C nopgp_autoencrypt nopgp_autosign"
          source ~/.mutt/send_hooks		# This is where I keep all my specific send hooks
          
        4. Set up per-friend send-hooks If you don't want to sign/encrypt everything, this is a good solution. Put these hooks either in your .muttrc or another file that is sources.
          # Just sign
          send-hook (.*@.*cs\.wisc\.edu|my@friend.org) 'set pgp_autosign'
          
          # Sign and encrypt
          send-hook (friend1|friend2|friend3)@.*cs\.wisc\.edu|someone@else.net \
          	'set pgp_autoencrypt pgp_autosign
          
          # Outlook Users To encrypt
          ### Requires special patch!!!
          send-hook (outlook@losers.com) \
          	'set pgp_create_traditional=yes pgp_autosign pgp_autoencrypt'
          
          # Do neither (conflicts with above rule)
          send-hook (junkies@.*cs.wisc.edu) \
          	'set nopgp_autosign nopgp_autoencrypt'
          
      3. Pine
        1. Coming soon...
      4. Outlook (ewww)
        1. Coming soon...
    • Managing keys and trust

      Obviously, key management is at the heart of useful encryption. It is important to make sure all (and only) the keys that should be valid or trusted are. To refresh:

      
      'Validity' for a particular key refers to the knowledge that the key
      belongs to the person to whom you expect it to belong.  This knowledge
      comes about based on your trust in the people who have signed the key
      (including, but not limited to, the key owner).  
      
      'Trust' in a person is a property of your particular installation of
      GnuPG.  Trust is a private value that only you have to know about and
      refers to whether or not you trust the person's signature on a key to be
      as good as your signature on a key, and the degree to which that trust
      exists.  Initially, key owners have a trust value of 'unknown'.  You may
      give them a trust value of 'none' if they are known to improperly sign
      keys.  A value of 'marginal' means that they understand key signing and
      perform it properly.  A value of 'full' means that they have an
      excellent understanding of key signing and that you trust their
      signature on a key as well as if you had signed the key yourself.  
      
      By default, a key is considered valid if it is signed by at least one
      person to whom you give full trust, or it is signed by at least three
      people to whom you give marginal trust.  This can of course be
      reconfigured, and a lower number of marginally trusted owners would
      signify a smaller number of people who would have to conspire against
      you to pass a key off as valid. 
      
      Without the necessary trusted signatures, the key is not considered
      valid.  This does not necessarily mean that the key does not belong to
      whom you expect it to, but that the software is warning you that it has
      no way of knowing.  Obviously, the web of trust is the weak point in
      public key cryptography, but when used properly can introduce some level
      of assurance into the situation. 
      
      1. Signing a key

        When you get a key from someone (either from a signed email [automatic], by downloading it, or via gpg --recv-key [numeric_keyid]) you should verify that the key really belongs to them. This needs to be done in a secure (usually meaning off-line) manner. Call them up (if you know their voice) or meet in person (ask for photo ID if you don't know them personally).

        gpg --fingerprint [key owner name]
        compare fingerprint with what they read to you
        gpg --sign-key [key owner name] 

        Remember that when you add trust you a key, you're not just trusting your friend, but also all the keys he has signed.

      2. Adding trust to a key
        gpg --edit-key [key owner name]
        trust
      3. Letting other people know of your trust
        gpg --send-keys

    • Using gpg elsewhere
      1. Encrypting files
        1. I use the following functions in zsh to tar up a bunch of files and gpg it all in one steop. It uses the default key and encrpt-to that we setup before, but you could change that on the command line. Feel free to send suggestions or ports to other shells.
          gtar () {
              declare -a the_args
              the_args=( $@ )
              file=$the_args[1]
              file=`echo $file|sed -e 's/\.tar\.gpg$//'`
              the_args[1]=		# shift off the first argument
              `tar cvf - ${the_args[*]} |gpg -z 9 -se -o $file.tar.gpg`
          }
          guntar () { gpg -d $1 |tar xvf - }	
          
      2. Editing encrypted text
        1. VIM: I put the following in .vim/gpg and source that file from .vimrc
          if has("autocmd")
          
          " Support editing of gpg-encrypted files
          augroup gnupg
          	" Remove all gnupg autocommands
          	au!
          
          	
          	" Enable editing of gpg-encrypted files
          	"			 read: set binary mode before reading the file
          	"						 decrypt text in buffer after reading
          	"			write: encrypt file after writing
          	"		 append: decrypt file, append, encrypt file
          	autocmd BufReadPre,FileReadPre      *.gpg set bin
          	autocmd BufReadPre,FileReadPre      *.gpg let ch_save = &ch|set ch=2
          	autocmd BufReadPost,FileReadPost    *.gpg '[,']!gpg -d 2>/dev/null
          	autocmd BufReadPost,FileReadPost    *.gpg set nobin
          	autocmd BufReadPost,FileReadPost    *.gpg let &ch = ch_save|unlet ch_save
          	autocmd BufReadPost,FileReadPost    *.gpg execute ":doautocmd BufReadPost " . expand("%:r")
          	autocmd BufReadPost,FileReadPost    *.gpg set tw=78
          
          	autocmd BufWritePost,FileWritePost  *.gpg !mv  :r
          	autocmd BufWritePost,FileWritePost  *.gpg !gpg -e :r
          	autocmd BufWritePost,FileWritePost  *.gpg !rm :r
          
          	autocmd FileAppendPre               *.gpg !gpg -d 2>/dev/null 
          	autocmd FileAppendPre               *.gpg !mv :r 
          	autocmd FileAppendPost              *.gpg !mv  :r
          	autocmd FileAppendPost              *.gpg !gpg -e :r
          	autocmd FileAppendPost              *.gpg !rm :r
          
          	" Same as above, but for ASCII-armored files
          	autocmd BufReadPre,FileReadPre      *.asc set bin
          	autocmd BufReadPre,FileReadPre      *.asc let ch_save = &ch|set ch=2
          	autocmd BufReadPost,FileReadPost    *.asc '[,']!gpg -d 2>/dev/null
          	autocmd BufReadPost,FileReadPost    *.asc set nobin
          	autocmd BufReadPost,FileReadPost    *.asc let &ch = ch_save|unlet ch_save
          	autocmd BufReadPost,FileReadPost    *.asc execute ":doautocmd BufReadPost " . expand("%:r")
          
          	autocmd BufWritePost,FileWritePost  *.asc !mv  :r
          	autocmd BufWritePost,FileWritePost  *.asc !gpg -a -e :r
          	autocmd BufWritePost,FileWritePost  *.asc !rm :r
          
          	autocmd FileAppendPre               *.asc !gpg -d 2>/dev/null 
          	autocmd FileAppendPre               *.asc !mv :r 
          	autocmd FileAppendPost              *.asc !mv  :r
          	autocmd FileAppendPost              *.asc !gpg -a -e :r
          	autocmd FileAppendPost              *.asc !rm :r
          augroup END
          
          endif
          		
      3. Easily grabbing keys
        1. This is a small perl script to grab pgp keys from the web. It relies on HTML::Parse and I'm sure there are easier ways to do this, but it works. Run gpg_lookup [email or other identifier]
          #!/usr/bin/perl
          
          use LWP::Simple;
          use HTML::Parse;
          use HTML::FormatText;
          use Term::ReadLine;
          
          my $server = 'http://pgp.dtype.org:11371/pks/lookup?op=index&search=';
          my $term = Term::ReadLine->new("Which selection?");
          my $OUT = $term->OUT || *STDOUT;
          
          
          
          foreach $name (@ARGV)
          {
          	$URL = $server.$name;
          	unless (defined ($content = get $URL)) {
          	    die "could not get $URL\n";
          	}
          	@chunks = split(/\n/, HTML::FormatText->new->format(parse_html($content)));
          	foreach $chunk (@chunks)
          	{
          		push @matches, $chunk if $chunk =~ m/(.*pub\s+(512|1024|2048|4096).*)/;
          	}
          
          
          	for (my $i=0; $i<=$#matches; $i++)
          	{
          		$line = $matches[$i];
          		$line =~ s/(<)\s+/$1/g;
          		$line =~ s/\s+(>)/$1/g;
          		print sprintf("%d) ", $i),"$line\n";
          	}
          
          	print "No keys found\n" and exit if $#matches < 0;
          
          	$input = 0 if $#matches<=0;
          	while (not defined($input))
          	{
          		$input = $term->readline("Which selection? ");
          		undef $input unless $input =~ m/^\d+$/ and $input >= 0 and $input <= $#matches;
          	}
          	print "Adding $input to gpg keyring\n";
          	$matches[$input] =~ m/.*pub\s+(?:512|1024|2048|4096)\s*\/\s*([\w\d]+).*/;
          	$keyid = $1;
          	print `gpg --recv-keys $keyid`;
          }