Using GnuPG with QubesOS

So Alice and Bob want to exchange private emails and files.

They realise that secure endpoint operating systems are an absolute requirement for any real privacy. What’s the point of protecting data in transit with PGP, when the spooks can remotely take over your machine and grab your stuff from the source? So they’ve taken the time to learn how to use Qubes OS – a security-by-separation operating system based on Xen and Fedora GNU/Linux.

Alice and Bob will use the non-networked “vault” AppVM to create and store their master cryptographic keys. They will then create a “daily use” keypair which will be available to their “personal” AppVM to send emails to each other.

Note: OpenPGP key management is complicated. To protect you from mistakes, this tutorial sets the expiry date of keys to one week after their creation. Once you are comfortable with this process you can always extend the life of your keys.

Create a new keypair

[user@vault ~]$ gpg --gen-key
gpg (GnuPG) 1.4.14; Copyright (C) 2013 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.

gpg: directory `/home/alice/.gnupg' created
gpg: new configuration file `/home/alice/.gnupg/gpg.conf' created
gpg: WARNING: options in `/home/alice/.gnupg/gpg.conf' are not yet active during this run
gpg: keyring `/home/alice/.gnupg/secring.gpg' created
gpg: keyring `/home/alice/.gnupg/pubring.gpg' created
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? 1
RSA keys may be between 1024 and 4096 bits long.
What keysize do you want? (2048) 4096
Requested keysize is 4096 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) 1w
Key expires at Thu Aug 22 18:38:49 2013 BST
Is this correct? (y/N) y

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: Alice
Email address: alice@domain.com
Comment:
You selected this USER-ID:
"Alice <alice@domain.com>"

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

Enter passphrase: <Alice's long passphrase>
Repeat passphrase: <Alice's long passphrase>
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.

Not enough random bytes available.  Please do some other work to give
the OS a chance to collect more entropy! (Need 246 more bytes)
..............+++++
gpg: /home/alice/.gnupg/trustdb.gpg: trustdb created
gpg: key 32D49659 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:   1  signed:   0  trust: 0-, 0q, 0n, 0m, 0f, 1u
gpg: next trustdb check due at 2013-08-22
pub   4096R/32D49659 2013-08-15 [expires: 2013-08-22]
Key fingerprint = 0346 5C7A 6412 A70B ED13  0196 9652 5380 32D4 9659
uid                  Alice <alice@domain.com>
sub   4096R/E19F81C0 2013-08-15 [expires: 2013-08-22]

[user@vault ~]$

Set strong cipher preferences

[user@vault ~]$ gpg --edit-key alice
gpg (GnuPG) 1.4.14; Copyright (C) 2013 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.

Secret key is available.

pub  4096R/32D49659  created: 2013-08-15  expires: 2013-08-22  usage: SC
trust: ultimate      validity: ultimate
sub  4096R/E19F81C0  created: 2013-08-15  expires: 2013-08-22  usage: E
[ultimate] (1). Alice <alice@domain.com>

gpg> setpref SHA512 SHA384 SHA256 SHA224 AES256 AES192 AES CAST5 ZLIB BZIP2 ZIP
Set preference list to:
Cipher: AES256, AES192, AES, CAST5, 3DES
Digest: SHA512, SHA384, SHA256, SHA224, SHA1
Compression: ZLIB, BZIP2, ZIP, Uncompressed
Features: MDC, Keyserver no-modify
Really update the preferences? (y/N) y

You need a passphrase to unlock the secret key for
user: "Alice <alice@domain.com>"
4096-bit RSA key, ID 32D49659, created 2013-08-15

Enter passphrase: <Alice's long passphrase>
pub  4096R/32D49659  created: 2013-08-15  expires: 2013-08-22  usage: SC
trust: ultimate      validity: ultimate
sub  4096R/E19F81C0  created: 2013-08-15  expires: 2013-08-22  usage: E
[ultimate] (1). Alice <alice@domain.com>

gpg> save
[user@vault ~]$

Add a signing subkey

[user@vault ~]$ gpg --edit-key alice
gpg (GnuPG) 1.4.14; Copyright (C) 2013 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.

Secret key is available.

pub  4096R/32D49659  created: 2013-08-15  expires: 2013-08-22  usage: SC
trust: ultimate      validity: ultimate
sub  4096R/E19F81C0  created: 2013-08-15  expires: 2013-08-22  usage: E
[ultimate] (1). Alice <alice@domain.com>

gpg> addkey
Key is protected.

You need a passphrase to unlock the secret key for
user: "Alice <alice@domain.com>"
4096-bit RSA key, ID 32D49659, created 2013-08-15

Enter passphrase: <Alice's long passphrase>
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? 4
RSA keys may be between 1024 and 4096 bits long.
What keysize do you want? (2048) 4096
Requested keysize is 4096 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) 1w
Key expires at Thu Aug 22 18:53:32 2013 BST
Is this correct? (y/N) y
Really create? (y/N) y
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.

Not enough random bytes available.  Please do some other work to give
the OS a chance to collect more entropy! (Need 269 more bytes)
.+++++
...........................+++++

pub  4096R/32D49659  created: 2013-08-15  expires: 2013-08-22  usage: SC
trust: ultimate      validity: ultimate
sub  4096R/E19F81C0  created: 2013-08-15  expires: 2013-08-22  usage: E
sub  4096R/29E78F35  created: 2013-08-15  expires: 2013-08-22  usage: S
[ultimate] (1). Alice <alice@domain.com>

gpg> save
[user@vault ~]$

Generate a revocation certificate

A general-purpose revocation certificate that specifies no reason why you are revoking your keys:

[user@vault ~]$ gpg --output revocation.cert --gen-revoke alice

sec  4096R/32D49659 2013-08-15 Alice <alice@domain.com>

Create a revocation certificate for this key? (y/N) y
Please select the reason for the revocation:
0 = No reason specified
1 = Key has been compromised
2 = Key is superseded
3 = Key is no longer used
Q = Cancel
(Probably you want to select 1 here)
Your decision? 0
Enter an optional description; end it with an empty line:
>
Reason for revocation: No reason specified
(No description given)
Is this okay? (y/N) y

You need a passphrase to unlock the secret key for
user: "Alice <alice@domain.com>"
4096-bit RSA key, ID 32D49659, created 2013-08-15

Enter passphrase: <Alice's long passphrase>
ASCII armored output forced.
Revocation certificate created.

Please move it to a medium which you can hide away; if Mallory gets
access to this certificate he can use it to make your key unusable.
It is smart to print this certificate and store it away, just in case
your media become unreadable.  But have some caution:  The print system of
your machine might store the data and make it available to others!
[user@vault ~]$

Backup your precious master keys and revocation certificate

Create a backup of Alice’s private key:

[user@vault ~]$ gpg --export-secret-keys --armor alice > alice_gpg_private.key

Create a backup of Alice’s public key:

[user@vault ~]$ gpg --export --armor alice > alice_gpg_public.key

Keep these files safe!

[user@vault ~]$ tar -cf gpg_master_keys.tar alice_gpg*.key revocation.cert

The file gpg_master_keys.tar contains everything one needs to fully impersonate Alice or invalidate her keys, except for her passphrase.

Shred the files we backed up – now everything is in the tar file:

[user@vault ~]$ shred -u alice_gpg*.key revocation.cert

Create a daily-use keyring

This keyring will *not* include your master signing key. It will be a restricted, lesser keyring, which you can expose to untrusted environments (like your smartphone, or your networked AppVMs).

Export all subkeys to a temporary file:

[user@vault ~]$ gpg --export-secret-subkeys alice@domain.com > subkeys

Delete your master signing key from your keyring:

[user@vault ~]$ gpg --delete-secret-key alice@domain.com
 gpg (GnuPG) 1.4.14; Copyright (C) 2013 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.
sec 4096R/32D49659 2013-08-15 Alice <alice@domain.com>
Delete this key from the keyring? (y/N) y
 This is a secret key! - really delete? (y/N) y
 [user@vault ~]$

Re-import the subkeys we exported earlier.

[user@vault ~]$ gpg --import subkeys
 gpg: key 32D49659: secret key imported
 gpg: key 32D49659: "Alice <alice@domain.com>" 1 new signature
 gpg: Total number processed: 1
 gpg: new signatures: 1
 gpg: secret keys read: 1
 gpg: secret keys imported: 1
 [user@vault ~]$

Get rid of the temporary file:

[user@vault ~]$ shred -u subkeys

Verify that the master signing key is missing:

[user@vault ~]$ gpg -K
 /home/alice/.gnupg/secring.gpg
 -----------------------------
 sec# 4096R/32D49659 2013-08-15 [expires: 2013-08-22]
 uid Alice <alice@domain.com>
 ssb 4096R/E19F81C0 2013-08-15
 ssb 4096R/29E78F35 2013-08-15
[user@vault ~]$

See that “#”? That means that the master signing key is not there. Congratulations – this is your daily-use, lower-risk keyring! It only contains Alice’s encryption and signing subkeys, but no master (certification) signing key.

Move the daily-use keyring to Alice’s “personal” AppVM

Alice runs her email client and exchanges email with Bob using her “personal” AppVM. She therefore needs to have her daily-use keyring there.

Export Alice’s “lesser” private key:

[user@vault ~]$ gpg --export-secret-keys --armor alice > alice_gpg_private_lesser.key

Export Alice’s “lesser” public key:

[user@vault ~]$ gpg --export --armor alice > alice_gpg_public_lesser.key

Copy these out of the vault and into Alice’s networked “personal” AppVM:

[user@vault ~]$ qvm-copy-to-vm personal alice_gpg_p*_lesser.key
sent 14/15 KB
[user@vault ~]$

You will be prompted by Qubes if you want to allow this transfer. Click “Yes” to allow your “vault” AppVM to write to your “personal” AppVM.

Install Alice’s daily-use keyring in the “personal” AppVM

First, Alice needs to import the keys into her keyring:

[user@personal ~]$ cd QubesIncoming/vault/
[user@personal vault]$ gpg --import alice_gpg_p*_lesser.key
gpg: directory `/home/user/.gnupg' created
gpg: new configuration file `/home/user/.gnupg/gpg.conf' created
gpg: WARNING: options in `/home/user/.gnupg/gpg.conf' are not yet active during this run
gpg: keyring `/home/user/.gnupg/secring.gpg' created
gpg: keyring `/home/user/.gnupg/pubring.gpg' created
gpg: key 46205B22: secret key imported
gpg: /home/user/.gnupg/trustdb.gpg: trustdb created
gpg: key 46205B22: public key "Alice <alice@domain.com>" imported
gpg: key 46205B22: "Alice <alice@domain.com>" 1 new signature
gpg: Total number processed: 2
gpg:               imported: 1  (RSA: 1)
gpg:         new signatures: 1
gpg:       secret keys read: 1
gpg:   secret keys imported: 1
[user@personal vault]$

Verify that the keys are there, but not the master certification key:

[user@personal vault]$ gpg -K
/home/user/.gnupg/secring.gpg
-----------------------------
sec#  4096R/46205B22 2013-10-04 [expires: 2013-10-11]
uid                  Alice <alice@domain.com>
ssb   4096R/DB739DBC 2013-10-04
ssb   4096R/E58DA355 2013-10-04
[user@personal vault]$

Good. That “#” means the certification key is not there.

Alice can now get rid of the exported key files:

[user@personal vault]$ shred -u alice_gpg_p*_lesser.key

At this point, Alice’s setup is done.

Here is what Alice has achieved:

  1. Alice has generated new OpenPGP keys in a secure environment (the vault)
  2. Alice created a “lesser” version of her keyring that excludes the all-important certification key. This “lesser” version will be used for daily use to communicate with Bob and anyone else using OpenPGP. If this “lesser” version of her keys is stolen (e.g. because the attacker compromises Alice’s “personal” AppVM), the attacker will not be able to create more keys in Alice’s name, or assign Alice’s trust to other keys. Alice only has to revoke her key and the attacker is left with nothing.
  3. Alice created a backup of her full certification keyring in a secure environment, the vault.

Publishing your public key on a keyserver for others to find

She should publish her key on the keyservers so that her friend Bob can easily find it: (note that the key to be sent must be selected with its key ID:

[user@personal ~]$ gpg --list-keys
/home/user/.gnupg/pubring.gpg
-----------------------------
pub   4096R/32D49659 2013-08-15 [expires: 2013-08-22]
uid                  Alice <alice@domain.com>
sub   4096R/E19F81C0 2013-08-15 [expires: 2013-08-22]
sub   4096R/29E78F35 2013-08-15 [expires: 2013-08-22]

[user@personal ~]$

So, let’s send key ID 32D49659 to the keyservers:

[user@personal ~]$ gpg --keyserver sks.keyservers.net --send-keys 32D49659
 gpg: sending key 32D49659 to hkp server sks.keyservers.net
 [user@personal ~]$

By knowing her public key’s fingerprint…

[user@personal ~]$ gpg --fingerprint alice@domain.com
 pub 4096R/32D49659 2013-08-15 [expires: 2013-08-22]
 Key fingerprint = 0346 5C7A 6412 A70B ED13 0196 9652 5380 32D4 9659
 uid Alice <alice@domain.com>
 sub 4096R/E19F81C0 2013-08-15 [expires: 2013-08-22]
 sub 4096R/29E78F35 2013-08-15 [expires: 2013-08-22]
[user@personal ~]$

…Alice can verify her key has been successfully published. All she needs to do is visit http://sks.keyservers.net/ and search for her email or name, then verify that the fingerprint shown matches the one of her local key.

In the meantime, Bob has been busy doing these exact same steps on his computer, for his name and email address. His key, tied to his email address bob@domain.com has also been published to the keyservers. He has also taken a proactive security precaution and only exposed a “lesser” version of his keyring to his networked AppVMs, with his certification key safely stored in the vault.

Communicating

Alice and Bob want to send private emails to each others. Emails about apple pie and silly gossip and deep meaningful conversations. It doesn’t matter. They just want to keep their conversations private. If they’ve both followed the steps above, this is what they need to do to email each other in private.

Importing Bob’s key

Alice needs to import Bob’s (public) key from the keyservers. She asks the keyserver to find Bob’s key:

[user@personal ~]$ gpg --keyserver sks.keyservers.net --search-keys bob@domain.com
gpg: searching for "bob@domain.com" from hkp server sks.keyservers.net
(1)	Robert <bob@domain.com>
	  4096 bit RSA key F19F159D, created: 2013-08-15, expires: 2013-08-22
(2)	Waldemar Retzlaff (Schlüssel zur domain.) <bob@eu-wedding.com>
	  1024 bit DSA key 96268EF6, created: 2003-12-16
Keys 1-2 of 2 for "bob@domain.com".  Enter number(s), N)ext, or Q)uit > 1
gpg: requesting key F19F159D from hkp server sks.keyservers.net
gpg: key F19F159D: public key "Robert <bob@domain.com>" imported
gpg: Total number processed: 1
gpg:               imported: 1  (RSA: 1)
[user@personal ~]$

Whoops – found multiple keys – but once she selected Bob’s key, it was automatically imported into Alice’s keyring.

Verifying Bob’s key

Alice can already use this key to send Bob private email messages or files, but she wants to be really really certain that is Bob’s key, and not some impostor’s! Alice either meets or calls Bob on the phone and asks him to read out to her his key’s fingerprint. She verifies it matches the fingerprint of the key she imported from the keyservers:

[user@personal ~]$ gpg --fingerprint bob@domain.com
pub   4096R/F19F159D 2013-08-15 [expires: 2013-08-22]
      Key fingerprint = FF24 73AF 8658 5280 85A4  C2BD 4440 516C F19F 159D
uid                  Robert <bob@domain.com>
sub   4096R/E12896F5 2013-08-15 [expires: 2013-08-22]
sub   4096R/734A2C3B 2013-08-15 [expires: 2013-08-22]

[user@personal ~]$

While they’re on the phone, Bob quickly imports Alice’s key from the keyserver and asks her to confirm her key’s fingerprint as well. Alice reads out her key’s fingerprint:

[user@personal ~]$ gpg --fingerprint alice@domain.com
pub   4096R/32D49659 2013-08-15 [expires: 2013-08-22]
      Key fingerprint = 0346 5C7A 6412 A70B ED13  0196 9652 5380 32D4 9659
uid                  Alice <alice@domain.com>
sub   4096R/E19F81C0 2013-08-15 [expires: 2013-08-22]
sub   4096R/29E78F35 2013-08-15 [expires: 2013-08-22]

[user@personal ~]$

Fingerprints of public keys are public information. So Alice and Bob don’t need to worry about other people listening in. Their fingerprints are not secret.

Great! So far Alice and Bob have generated and successfully exchanged keys. Now all they need to do is use an application like Thunderbird with the Enigmail plugin (on Windows/Mac/Linux) or K9 with the APG app (on Android) to exchange encrypted and signed emails and files, being pretty certain that nobody can read or alter the contents of their messages.

When disaster strikes

Oh no! Alice’s smartphone has been stolen! Or one of her AppVMs might have opened an infected PDF, or ran some suspicious Java applet that might have installed a trojan on her personal AppVM. Nothing in that AppVM can be trusted any longer. This includes the GnuPG keys she was using on a daily basis.

Luckily Alice is prepared.

Revoking compromised keys

Alice needs to use her safe environment (the vault) to revoke the compromised subkeys (she only exposed subkeys to her networked AppVMs and devices, remember?) and optionally issue new ones.

The beauty of this is that she does not have to throw away the whole key. Alice can carry on using the same master key, which may, over the years, have accumulated a lot of trust from other Web Of Trust members. She just needs to revoke the compromised subkeys and issue new ones.

Working with our master key

Alice fires up her vault and imports the master keyring she had backed up when she created her keys:

[user@vault ~]$ tar xvf gpg_master_keys.tar
alice_gpg_private.key
alice_gpg_public.key
revocation.cert
[user@vault ~]$ 

Here are the files Alice backed up. Let’s import them to start using them – but first temporarily move .gnupg out of the way to ensure we’re not upsetting any preexisting configuration in the vault:

[user@vault ~]$ mv .gnupg .gnupg-ORIG
[user@vault ~]$ gpg --import alice_gpg_p*.key
gpg: directory `/home/user/.gnupg' created
gpg: new configuration file `/home/user/.gnupg/gpg.conf' created
gpg: WARNING: options in `/home/user/.gnupg/gpg.conf' are not yet active during this run
gpg: keyring `/home/user/.gnupg/secring.gpg' created
gpg: keyring `/home/user/.gnupg/pubring.gpg' created
gpg: key 32D49659: secret key imported
gpg: /home/user/.gnupg/trustdb.gpg: trustdb created
gpg: key 32D49659: public key "Alice <alice@domain.com>" imported
gpg: key 32D49659: "Alice <alice@domain.com>" 1 new signature
gpg: Total number processed: 2
gpg:               imported: 1  (RSA: 1)
gpg:         new signatures: 1
gpg:       secret keys read: 1
gpg:   secret keys imported: 1
[user@vault ~]$

Verify what we imported:

[user@vault ~]$ gpg --edit-key alice
gpg (GnuPG) 1.4.14; Copyright (C) 2013 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.

Secret key is available.

pub  4096R/32D49659  created: 2013-08-15  expires: 2013-08-22  usage: SC  
                     trust: unknown       validity: unknown
sub  4096R/E19F81C0  created: 2013-08-15  expires: 2013-08-22  usage: E   
sub  4096R/29E78F35  created: 2013-08-15  expires: 2013-08-22  usage: S   
[ unknown] (1). Alice <alice@domain.com>

gpg>

Yup, there they are.

  • The all-important master key with usage: SC (for “sign & certify”, which means to sign other keys)
  • One subkey with usage: E – for “encrypt”
  • One subkey with usage: S – for “sign”

Revoking compromised subkeys

gpg> list

pub  4096R/32D49659  created: 2013-08-15  expires: 2013-08-22  usage: SC  
                     trust: unknown       validity: unknown
sub  4096R/E19F81C0  created: 2013-08-15  expires: 2013-08-22  usage: E   
sub  4096R/29E78F35  created: 2013-08-15  expires: 2013-08-22  usage: S   
[ unknown] (1). Alice <alice@domain.com>

gpg> key 1

pub  4096R/32D49659  created: 2013-08-15  expires: 2013-08-22  usage: SC  
                     trust: unknown       validity: unknown
sub* 4096R/E19F81C0  created: 2013-08-15  expires: 2013-08-22  usage: E   
sub  4096R/29E78F35  created: 2013-08-15  expires: 2013-08-22  usage: S   
[ unknown] (1). Alice <alice@domain.com>

gpg> key 2

pub  4096R/32D49659  created: 2013-08-15  expires: 2013-08-22  usage: SC  
                     trust: unknown       validity: unknown
sub* 4096R/E19F81C0  created: 2013-08-15  expires: 2013-08-22  usage: E   
sub* 4096R/29E78F35  created: 2013-08-15  expires: 2013-08-22  usage: S   
[ unknown] (1). Alice <alice@domain.com>

gpg> revkey
Do you really want to revoke the selected subkeys? (y/N) y
Please select the reason for the revocation:
  0 = No reason specified
  1 = Key has been compromised
  2 = Key is superseded
  3 = Key is no longer used
  Q = Cancel
Your decision? 1
Enter an optional description; end it with an empty line:
> 
Reason for revocation: Key has been compromised
(No description given)
Is this okay? (y/N) y

You need a passphrase to unlock the secret key for
user: "Alice <alice@domain.com>"
4096-bit RSA key, ID 32D49659, created 2013-08-15

You need a passphrase to unlock the secret key for
user: "Alice <alice@domain.com>"
4096-bit RSA key, ID 32D49659, created 2013-08-15

pub  4096R/32D49659  created: 2013-08-15  expires: 2013-08-22  usage: SC  
                     trust: unknown       validity: unknown
This key was revoked on 2013-08-16 by RSA key 32D49659 Alice <alice@domain.com>
sub  4096R/E19F81C0  created: 2013-08-15  revoked: 2013-08-16  usage: E   
This key was revoked on 2013-08-16 by RSA key 32D49659 Alice <alice@domain.com>
sub  4096R/29E78F35  created: 2013-08-15  revoked: 2013-08-16  usage: S   
[ unknown] (1). Alice <alice@domain.com>

gpg> save
[user@vault ~]$

As you can see the all-important certification key has the power to revoke subkeys. Good thing Alice kept it safe in her offline vault all this time!

Export the revoked keys in a ASCII file

[user@vault ~]$ gpg --export -a > revoked_keys.asc

Move the revoked keys in your networked AppVM

[user@vault ~]$ qvm-copy-to-vm personal revoked_keys.asc 
sent 7/8 KB
[user@vault ~]$

From your networked AppVM now, tell the world you have revoked the subkeys

[user@personal ~]$ gpg --import QubesIncoming/vault/revoked_keys.asc 
gpg: key 32D49659: "Alice <alice@domain.com>" 2 new signatures
gpg: Total number processed: 1
gpg:         new signatures: 2

[user@personal ~]$ gpg --edit-key alice
gpg (GnuPG) 1.4.14; Copyright (C) 2013 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.

Secret key is available.

pub  4096R/32D49659  created: 2013-08-15  expires: 2013-08-22  usage: SC  
                     trust: ultimate      validity: ultimate
This key was revoked on 2013-08-16 by RSA key 32D49659 Alice <alice@domain.com>
sub  4096R/E19F81C0  created: 2013-08-15  revoked: 2013-08-16  usage: E   
This key was revoked on 2013-08-16 by RSA key 32D49659 Alice <alice@domain.com>
sub  4096R/29E78F35  created: 2013-08-15  revoked: 2013-08-16  usage: S   
[ultimate] (1). Alice <alice@domain.com>

gpg> quit

[user@personal ~]$ gpg --keyserver sks.keyservers.net --send-keys E19F81C0
gpg: sending key 32D49659 to hkp server sks.keyservers.net
[user@personal ~]$ gpg --keyserver sks.keyservers.net --send-keys 29E78F35
gpg: sending key 32D49659 to hkp server sks.keyservers.net
[user@personal ~]$ rm QubesIncoming/vault/revoked_keys.asc
[user@personal ~]

That’s it!

You have now revoked the two compromised subkeys and may create new subkeys with your untainted master key that was kept safe in your vault all along. Whoever managed to compromise your keys may be able to read everything encrypted with those keys (if they kept copies of the ciphertext).

Notes

Restricted keys (missing the master signing key, as we created above) can not currently be used by APG on Android. Use Mike Cardwell’s version of APG that works with such keys: download the apk from here.

Leave a comment