# gpg (and a bit about ecryptfs) # (January 2017) ## Symmetric ## Encrypt a file with a symmetric cipher using a passphrase: $ gpg -ac myfile.txt This produces myfile.txt.asc. `-c` is short for `--symmetric`. To send the out cipher text to STDOUT instead: $ gpg -o - -ac myfile.txt (The `-a` flag outputs ASCII rather than binary. ASCII is more portable; gpg ASCII output may be safely pasted into an email, for example.) Note that after encrypting a file, gpg leaves the original in place, unmodified. Remember to securely delete the original file, if it shouldn't be left sitting around in plain text. See shred(1), although it's unclear how well secure delete utilities work on an SSD. Using an encrypted disk partition or directory may be a better bet. Decrypt the file (plain text goes to STDOUT by default): $ gpg -d myfile.txt.asc Or, send the plain text to a file: $ gpg -io myfile.txt -d myfile.txt.asc ## Asymmetric ## Generate a public/private key pair: $ gpg --gen-key This generates a bunch of files in `$HOME/.gnupg`. List the keys with: $ gpg --list-keys In fact with `gpg --list-keys` and `gpg --list-secret-keys`, we see that GPG generated a number of keys: - "pub [SC]" the public signing master key - "sec [SC]" the secret/private signing master key - "sub [E]" the public encryption subkey (see the "Subkeys" section below) - "ssb [E]" the secret/private encryption subkey (see the "Subkeys" section below) Ideally, use of the master key pair should be confined to generating subkeys. We use subkeys for our day-to-day work. We differentiate between signing and encryption keys. Signing keys protect our identity; the "web of trust" is tied to signing keys. Encryption keys protect our data. Encryption keys should be escrowed (backed up somewhere), but signing keys should not. For some operations, we must refer to a "keyid", which we can find with: $ gpg --list-keys --keyid-format short $ gpg --list-keys --keyid-format long It's a good idea to generate a revocation certificate now, at leisure, rather than when desperate: $ gpg -ao $HOME/.gnupg/revocation_cert.asc --gen-revoke me@example.com Export your public key to a file: $ gpg -ao me_pubkey.gpg --export me@example.com Spit the public key out to the command line: $ gpg --armor --export me@example.com $ gpg --armor --export 08D01274 Send the key to a public keyserver: $ gpg --send-keys --keyserver keyserver.ubuntu.com ABCDEF123456ABCD Import someone else's key from a file: $ gpg --import someone_pubkey.gpg Import someone else's key from a public keyserver: $ gpg --keyserver pgp.mit.edu --search-keys 'John Smith' (This, in itself, does not guarantee the true identity of someone! Verify the correctness of the key with the person to be sure.) We may need outbound TCP port 11371 allowed on the firewall, although some keyservers listen on 443. Encrypting a message for someone else: $ gpg -ase -r someone@example.com -r me@example.com myfile.txt Note: without specifying '-r me@example.com', we won't be able to decrypt our own message. Omitting this may be useful, if we want to make it impossible for anyone to later compel us to decrypt the message. ### Signing vs Encrypting ### When encrypting a message to someone, we use their public (encryption) key so only they can read it. We sign a message with our private (signing) key. Someone can verify that we signed the message using our public (signing) key. But there's not necessarily much difference between a signing key and an encryption key, except how we use them. For that matter, public and private keys are the same, except in how we use them; we could encrypt a message with our public key, but it wouldn't be very secret. What if we want to verify our identity as the author of a public/plaintext message? We could encrypt the message with our public key, and distribute both the plaintext and ciphertext. Anyone would be able to see that decrypting the ciphertext using our public matches the plaintext, proving that we, the author, possesses the matching private key. Of course, this doubles the size of the message. Instead of sending ciphertext of the full message, we could send a cipher of a _hash_ of the message. The simplest way to do this: $ gpg --clearsign mymessage.txt ...which produces `mymessage.txt.asc`: the original plaintext with a PGP signature. See also the `--sign` and `--detatch-sign` flags. Or, to sent the ASCII-armored (by default the sig is output as OpenPGP-compatible binary) message signature to STDOUT: $ gpg --output - --armor --sign mymessage.txt Or: $ gpg --armor --detach-sign mymessage.txt To check a signed document: $ gpg --verify mymessage.txt.asc To debug what GPG is doing, and understand it better, use `--list-packets`: $ gpg --export-secret-keys | gpg --list-packets ## Subkeys ## Subkeys make key management safer and easier. Subkeys are like normal keys, except that they're bound to a master key pair. Subkeys bring two great benefits: - Subkeys can be revoked independently of their master key pair. - Subkeys can be stored and used separately from their master key pair. Imagine we have a laptop that might be stolen, but from which we still need to work. Keep the master key pair off the laptop; only install a subkey pair. If the laptop walks away, we revoke only the subkey, leaving the identity associated with our master key pair intact. GnuPG actually uses a signing-only key as the master key, and creates an encryption subkey automatically. It used this subkey for normal operation. Generating a subkey (signing and/or encryption): $ gpg --edit-key me@example.com gpg> addkey gpg> addkey Please select what kind of key you want: (3) DSA (sign only) (4) RSA (sign only) (5) Elgamal (encrypt only) (6) RSA (encrypt only) Your selection? 6 RSA keys may be between 1024 and 4096 bits long. What keysize do you want? (2048) Requested keysize is 2048 bits Please specify how long the key should be valid. 0 = key does not expire = key expires in n days w = key expires in n weeks m = key expires in n months y = key expires in n years Key is valid for? (0) 2y Key expires at Sat 15 Jun 2019 08:32:47 PM EDT Is this correct? (y/N) y Really create? (y/N) y Exporting a subkey for use on another device, while removing the master key: $ gpg --export-secret-subkeys ## Backing Up Encryption Keys (Key Escrow) ## Various methods exist. For electronic backups, archiving ~/.gnupg/ suffices. For paper backups, a program called `paperkey` helps: $ gpg --export-secret-key | paperkey Note that output varies from one run of the command to the next, because the exported key is still protected by our passphrase. Backing up the public keys is OK, but not strictly necessary. GnuPG and (re)generate the public keys from the private keys. ## Encrypted Directories ## Short of running full disk encryption, ecryptfs is a reasonable alternative to encrypt a particular directory. The `ecryptfs-setup-private` script make it easy to set up an encrypted `$HOME/Private/` directory. # apt-get install ecryptfs-utils # modprobe ecryptfs $ ecryptfs-setup-private This creates `~/.Private` (the encrypted directory "lower directory") and `~/.Private` (the unencrypted "upper directory" mount point). After logging out and logging in again: $ mount | grep Private /home/me/.Private on /home/me/Private type ecryptfs (rw,nosuid,nodev,relatime,ecryptfs_fnek_sig=a58f7aef132c31a7,ecryptfs_sig=318d1b73d90304a5,ecryptfs_cipher=aes,ecryptfs_key_bytes=16,ecryptfs_unlink_sigs) This directory should be automatically decrypted and mounted at login, and encrypted and unmounted at logout. RECORD THE MOUNT PASSPHRASE AND STORE IN A SAFE LOCATION. If the mount passphase file is lost, THERE IS NO WAY TO RECOVER THE ENCRYPTED DATA. Back up `~/.ecryptfs`! Note that ecryptfs is not reliable on network filesystems, including NFS. ## Links ## - https://www.gnupg.org/gph/en/manual/book1.html - https://futureboy.us/pgp.html - http://askubuntu.com/questions/57572/how-to-delete-files-in-secure-manner - https://wiki.archlinux.org/index.php/ECryptfs - http://www.ibm.com/support/knowledgecenter/linuxonibm/liaai.securerhel/liaaisecuresusermount.htm - https://alexcabal.com/creating-the-perfect-gpg-keypair/ - https://wiki.debian.org/Subkeys?action=show&redirect=subkeys - https://superuser.com/questions/632375/why-does-gpg-pgp-by-default-use-different-keys-for-signing-encryption - https://security.stackexchange.com/questions/8559/digital-certificate-deployment-using-two-certs-for-each-user/8563#8563 - https://stackoverflow.com/questions/454048/what-is-the-difference-between-encrypting-and-signing-in-asymmetric-encryption - https://www.gnupg.org/gph/en/manual.html#AEN136