2014-07-24 06:59:44 -04:00
|
|
|
|
---
|
2015-04-10 16:17:45 -04:00
|
|
|
|
layout: doc
|
2014-07-24 06:59:44 -04:00
|
|
|
|
title: SplitGpg
|
2015-09-22 04:09:52 -04:00
|
|
|
|
permalink: /doc/SplitGpg/
|
2015-09-22 05:02:22 -04:00
|
|
|
|
redirect_from:
|
|
|
|
|
- "/doc/UserDoc/SplitGpg/"
|
|
|
|
|
- "/wiki/UserDoc/SplitGpg/"
|
2014-07-24 06:59:44 -04:00
|
|
|
|
---
|
|
|
|
|
|
2014-07-24 11:25:52 -04:00
|
|
|
|
Qubes Split GPG
|
|
|
|
|
===============
|
2014-07-24 06:59:44 -04:00
|
|
|
|
|
2014-07-24 11:25:52 -04:00
|
|
|
|
What is Split GPG and why should I use it instead of the standard GPG?
|
|
|
|
|
----------------------------------------------------------------------
|
2015-09-22 14:00:52 -04:00
|
|
|
|
Split GPG implements a concept similar to having a smart card with your
|
|
|
|
|
private GPG keys, except that the role of the "smart card" plays another Qubes
|
|
|
|
|
AppVM. This way one, not-so-trusted domain, e.g. the one where Thunderbird is
|
|
|
|
|
running, can delegate all crypto operations, such as encryption/decryption
|
|
|
|
|
and signing to another, more trusted, network-isolated, domain. This way
|
|
|
|
|
a compromise of your domain where the Thunderbird or other client app is
|
|
|
|
|
running -- arguably a not-so-unthinkable scenario -- does not allow the
|
|
|
|
|
attacker to automatically also steal all your keys (we should make a rather
|
|
|
|
|
obvious comment here that the so-often-used passphrases on private keys are
|
|
|
|
|
pretty meaningless because the attacker can easily set up a simple backdoor
|
|
|
|
|
which would wait until the user enters the passphrase and steal the key then).
|
2014-07-24 06:59:44 -04:00
|
|
|
|
|
2014-07-24 11:25:52 -04:00
|
|
|
|
The diagram below presents the big picture of Split GPG architecture.
|
|
|
|
|
|
2015-09-22 12:26:25 -04:00
|
|
|
|
![split-gpg-diagram.png](/attachment/wiki/SplitGpg/split-gpg-diagram.png)
|
2014-07-24 11:25:52 -04:00
|
|
|
|
|
2015-09-22 13:29:54 -04:00
|
|
|
|
### Advantages of Split GPG vs. traditional GPG with a smart card ###
|
2014-07-24 11:25:52 -04:00
|
|
|
|
|
2015-09-22 14:00:52 -04:00
|
|
|
|
It is often thought that the use of smart cards for private key storage
|
|
|
|
|
guarantees ultimate safety. While this might be true (unless the attacker
|
|
|
|
|
can find a usually-very-expensive-and-requiring-physical-presence way to
|
|
|
|
|
extract the key from the smart card) but only with regards to the safety of
|
|
|
|
|
the private key itself. However, there is usually nothing that could stop
|
|
|
|
|
the attacker from requesting the smart card to perform decryption of all the
|
|
|
|
|
user documents the attacker has found or need to decrypt. In other words,
|
|
|
|
|
while protecting the user's private key is an important task, we should not
|
|
|
|
|
forget that ultimately it is the user data that are to be protected and that
|
|
|
|
|
the smart card chip has no way of knowing the requests to decrypt documents
|
|
|
|
|
are now coming from the attacker's script and not from the user sitting in
|
|
|
|
|
front of the monitor. (Similarly the smart card doesn't make the process
|
|
|
|
|
of digitally signing a document or a transaction in any way more secure --
|
|
|
|
|
the user cannot know what the chip is really signing. Unfortunately this
|
|
|
|
|
problem of signing reliability is not solvable by Split GPG)
|
|
|
|
|
|
|
|
|
|
With Qubes Split GPG this problem is drastically minimized, because each time
|
|
|
|
|
the key is to be used the user is asked for consent (with a definable time
|
|
|
|
|
out, 5 minutes by default), plus is always notified each time the key is used
|
|
|
|
|
via a tray notification from the domain where GPG backend is running. This
|
|
|
|
|
way it would be easy to spot unexpected requests to decrypt documents.
|
2014-07-24 11:25:52 -04:00
|
|
|
|
|
2015-09-22 13:29:54 -04:00
|
|
|
|
![r2-split-gpg-1.png](/attachment/wiki/SplitGpg/r2-split-gpg-1.png)
|
|
|
|
|
![r2-split-gpg-3.png](/attachment/wiki/SplitGpg/r2-split-gpg-3.png)
|
2014-07-24 06:59:44 -04:00
|
|
|
|
|
2015-09-22 13:29:54 -04:00
|
|
|
|
### Current limitations ###
|
2014-07-24 06:59:44 -04:00
|
|
|
|
|
2015-09-22 14:00:52 -04:00
|
|
|
|
- Current implementation requires importing of public keys to the vault
|
|
|
|
|
domain. This opens up an avenue to attack the gpg running in the backend domain
|
|
|
|
|
via a hypothetical bug in public key importing code. See ticket \#474 for more
|
|
|
|
|
details and plans how to get around this problem, as well as the section on
|
|
|
|
|
[using split GPG with subkeys](#advanced-using-split-gpg-with-subkeys) below.
|
2014-07-24 11:25:52 -04:00
|
|
|
|
|
2015-09-22 14:00:52 -04:00
|
|
|
|
- It doesn't solve the problem of allowing the user to know what is to be
|
|
|
|
|
signed before the operation gets approved. Perhaps the GPG backend domain
|
|
|
|
|
could start a Disposable VM and have the to-be-signed document displayed
|
|
|
|
|
there? To Be Determined.
|
|
|
|
|
|
|
|
|
|
- Verifying detached signatures does not work (see \#900). You have to have
|
|
|
|
|
public keys in AppVM and some means to use different command to verify
|
|
|
|
|
them. Both git and Enigmail does not allow that and you have to choose
|
|
|
|
|
between Split GPG and PGP/MIME.
|
2014-07-24 11:25:52 -04:00
|
|
|
|
|
2014-10-06 12:14:22 -04:00
|
|
|
|
|
2014-07-24 11:25:52 -04:00
|
|
|
|
Configuring and using Split GPG
|
|
|
|
|
-------------------------------
|
2015-09-22 14:00:52 -04:00
|
|
|
|
Start with creating a dedicated AppVM for storing your keys (the GPG backend
|
|
|
|
|
domain). It is recommended that this domain be network disconnected (set its
|
|
|
|
|
netvm to `none`) and only used for this one purpose. In later examples this
|
|
|
|
|
AppVM is named `work-gpg`, but of course it might have any other name.
|
2014-07-24 06:59:44 -04:00
|
|
|
|
|
2015-09-22 13:29:54 -04:00
|
|
|
|
### Setting up the GPG backend domain ###
|
2014-07-24 12:25:32 -04:00
|
|
|
|
|
2015-09-22 14:00:52 -04:00
|
|
|
|
Make sure the gpg is installed there and there are some private keys in the
|
|
|
|
|
keyring, e.g.:
|
2014-07-24 12:25:32 -04:00
|
|
|
|
|
2015-09-22 13:29:54 -04:00
|
|
|
|
[user@work-gpg ~]$ gpg -K
|
|
|
|
|
/home/user/.gnupg/secring.gpg
|
|
|
|
|
-----------------------------
|
|
|
|
|
sec 4096R/3F48CB21 2012-11-15
|
|
|
|
|
uid Qubes OS Security Team <security@qubes-os.org>
|
|
|
|
|
ssb 4096R/30498E2A 2012-11-15
|
|
|
|
|
(...)
|
2014-07-24 12:25:32 -04:00
|
|
|
|
|
2015-09-22 14:00:52 -04:00
|
|
|
|
This is pretty much all that is required. However one might also want to modify
|
|
|
|
|
the default timeout which tells the backend for how long the user's approval
|
|
|
|
|
for key access should be valid (default 5 minutes). This is adjustable via
|
|
|
|
|
`QUBES_GPG_AUTOACCEPT` variable. One can override it e.g. in `~/.bash_profile`:
|
2014-07-24 12:25:32 -04:00
|
|
|
|
|
2015-09-22 13:29:54 -04:00
|
|
|
|
[user@work-gpg ~]$ echo "export QUBES_GPG_AUTOACCEPT=86400" >> ~/.bash_profile
|
2014-07-24 12:25:32 -04:00
|
|
|
|
|
2015-09-22 13:29:54 -04:00
|
|
|
|
### Configuring the client apps to use split GPG backend ###
|
2014-07-24 12:25:32 -04:00
|
|
|
|
|
2015-09-22 14:00:52 -04:00
|
|
|
|
Normally it should be enough to set the `QUBES_GPG_DOMAIN` to the GPG backend
|
|
|
|
|
domain name and use `qubes-gpg-client` in place of `gpg`, e.g.:
|
2014-07-24 12:25:32 -04:00
|
|
|
|
|
2015-09-22 13:29:54 -04:00
|
|
|
|
[user@work ~]$ export QUBES_GPG_DOMAIN=work-gpg
|
|
|
|
|
[user@work ~]$ gpg -K
|
|
|
|
|
[user@work ~]$ qubes-gpg-client -K
|
|
|
|
|
/home/user/.gnupg/secring.gpg
|
|
|
|
|
-----------------------------
|
|
|
|
|
sec 4096R/3F48CB21 2012-11-15
|
|
|
|
|
uid Qubes OS Security Team <security@qubes-os.org>
|
|
|
|
|
ssb 4096R/30498E2A 2012-11-15
|
|
|
|
|
(...)
|
|
|
|
|
|
|
|
|
|
[user@work ~]$ qubes-gpg-client secret_message.txt.asc
|
|
|
|
|
(...)
|
2014-07-24 12:25:32 -04:00
|
|
|
|
|
2015-09-22 14:00:52 -04:00
|
|
|
|
Note that running normal `gpg -K` in the demo above shows no private keys
|
|
|
|
|
stored in this AppVM.
|
2014-07-24 12:42:46 -04:00
|
|
|
|
|
2015-09-22 13:29:54 -04:00
|
|
|
|
### Configuring Thunderbird/Enigmail for use with Split GPG ###
|
2014-07-30 03:42:19 -04:00
|
|
|
|
|
2015-09-22 14:00:52 -04:00
|
|
|
|
However, when using Thunderbird with Enigmail extension it is
|
|
|
|
|
not enough, because Thunderbird doesn't preserve the environment
|
|
|
|
|
variables. Instead it is recommended to use a simple script provided by
|
|
|
|
|
`/usr/bin/qubes-gpg-client-wrapper` file by pointing Enigmail to use this
|
|
|
|
|
script instead of the standard GnuPG binary:
|
2014-07-24 12:28:02 -04:00
|
|
|
|
|
2015-09-22 12:26:25 -04:00
|
|
|
|
![tb-enigmail-split-gpg-settings-2.png](/attachment/wiki/SplitGpg/tb-enigmail-split-gpg-settings-2.png)
|
2014-07-24 12:28:02 -04:00
|
|
|
|
|
2015-09-22 14:00:52 -04:00
|
|
|
|
The script also sets the QUBES\_GPG\_DOMAIN variable automatically based on
|
|
|
|
|
the content of the file `/rw/config/gpg-split-domain`, which should be set to
|
|
|
|
|
the name of the GPG backend VM. This file survives the AppVM reboot, of course.
|
2014-07-24 12:25:32 -04:00
|
|
|
|
|
2015-09-22 13:29:54 -04:00
|
|
|
|
[user@work ~]$ sudo bash
|
|
|
|
|
[user@work ~]$ echo "work-gpg" > /rw/config/gpg-split-domain
|
2014-07-24 06:59:44 -04:00
|
|
|
|
|
2015-09-22 14:00:52 -04:00
|
|
|
|
*NOTE*: A recent engimail update, version `thunderbird-enigmail-1.7-1`,
|
|
|
|
|
introduced changes in how Enigmail expects to execute GPG binary
|
|
|
|
|
and so requires an updated split-gpg package with version \>=
|
|
|
|
|
`qubes-gpg-split-2.0.7-1`. Please make sure you have all the latest qubes
|
|
|
|
|
packages installed in your template.
|
2014-07-30 03:42:19 -04:00
|
|
|
|
|
2015-09-22 13:29:54 -04:00
|
|
|
|
### How to use `gpg2` instead of `gpg` ###
|
2015-05-26 12:24:01 -04:00
|
|
|
|
|
|
|
|
|
In your GPG backend domain's TemplateVM:
|
|
|
|
|
|
|
|
|
|
1. `sudo vim /etc/qubes-rpc/qubes.Gpg`
|
|
|
|
|
2. Change `/usr/bin/gpg` to `/usr/bin/gpg2`.
|
2015-09-22 14:00:52 -04:00
|
|
|
|
3. Ensure that your key has a **blank passphrase**. If not, you will encounter
|
|
|
|
|
an error.
|
2015-05-26 12:24:01 -04:00
|
|
|
|
4. Shut down the TemplateVM and restart the GPG backend domain.
|
|
|
|
|
|
2015-09-22 13:29:54 -04:00
|
|
|
|
### Importing public keys ###
|
2014-07-24 12:40:04 -04:00
|
|
|
|
|
2015-09-22 14:00:52 -04:00
|
|
|
|
Use `qubes-gpg-import-key` in the client AppVM to import the key into the
|
|
|
|
|
GPG backend VM. Of course a (safe, unspoofable) user consent dialog box is
|
|
|
|
|
displayed to accept this.
|
2014-07-24 12:40:04 -04:00
|
|
|
|
|
2015-09-22 13:29:54 -04:00
|
|
|
|
[user@work ~]$ export QUBES_GPG_DOMAIN=work-gpg
|
|
|
|
|
[user@work ~]$ qubes-gpg-import-key ~/Downloads/marmarek.asc
|
2014-07-24 12:40:04 -04:00
|
|
|
|
|
2015-09-22 12:26:25 -04:00
|
|
|
|
![r2-split-gpg-5.png](/attachment/wiki/SplitGpg/r2-split-gpg-5.png)
|
2014-08-03 00:30:42 -04:00
|
|
|
|
|
2015-09-22 14:00:52 -04:00
|
|
|
|
<br />
|
|
|
|
|
|
2014-08-03 00:30:42 -04:00
|
|
|
|
Advanced: Using Split GPG with Subkeys
|
|
|
|
|
--------------------------------------
|
2015-09-22 14:00:52 -04:00
|
|
|
|
Users with particularly high security requirements may wish to use Split
|
|
|
|
|
GPG with [subkeys](https://wiki.debian.org/Subkeys). However, this setup
|
|
|
|
|
comes at a significant cost: It will be impossible to sign other people's keys
|
|
|
|
|
with the master secret key without breaking this security model. Nonetheless,
|
|
|
|
|
if signing others' keys is not required, then Split GPG with subkeys offers
|
|
|
|
|
unparalleled security for one's master secret key.
|
2014-08-03 00:30:42 -04:00
|
|
|
|
|
2015-09-22 13:29:54 -04:00
|
|
|
|
### Setup Description ###
|
2014-08-03 00:30:42 -04:00
|
|
|
|
|
2015-09-22 14:00:52 -04:00
|
|
|
|
In this example, the following keys are stored in the following locations
|
|
|
|
|
(see below for defintions of these terms):
|
2014-08-03 00:30:42 -04:00
|
|
|
|
|
2015-09-22 13:29:54 -04:00
|
|
|
|
| PGP Key(s) | VM Name |
|
|
|
|
|
| ---------- | ------------ |
|
|
|
|
|
| `sec` | `vault` |
|
|
|
|
|
| `ssb` | `work-gpg` |
|
|
|
|
|
| `pub` | `work-email` |
|
2014-08-03 00:30:42 -04:00
|
|
|
|
|
2015-09-22 14:00:52 -04:00
|
|
|
|
<br />
|
|
|
|
|
|
|
|
|
|
* `sec` (master secret key)
|
|
|
|
|
|
|
|
|
|
Depending on your needs, you may wish to create this as a **certify-only
|
|
|
|
|
(C)** key, i.e., a key which is capable only of signing (a.k.a.,
|
|
|
|
|
"certifying") other keys. This key may be created *without* an expiration
|
|
|
|
|
date. This is for two reasons. First, the master secret key is never to
|
|
|
|
|
leave the `vault` VM, so it is extremely unlikely ever to be obtained by
|
|
|
|
|
an adversary (see below). Second, an adversary who *does* manage to obtain
|
|
|
|
|
the master secret key either possesses the passphrase to unlock the key
|
|
|
|
|
(if one is used), or he does not. If he does, then he can simply use
|
|
|
|
|
the passphrase in order to legally extend the expiration date of the key
|
|
|
|
|
(or remove it entirely). If he does not, then he cannot use the key at
|
|
|
|
|
all. In either case, an expiration date provides no additional benefit.
|
|
|
|
|
|
|
|
|
|
By the same token, however, having a passphrase on the key is of little
|
|
|
|
|
value. An adversary who is capable of stealing the key from your `vault`
|
|
|
|
|
would almost certainly also be capable of stealing the passphrase as
|
|
|
|
|
you enter it. An adversary who obtains the passphrase can then use it
|
|
|
|
|
in order to change or remove the passphrase from the key. Therefore,
|
|
|
|
|
using a passphrase at all should be considered optional. It is, however,
|
|
|
|
|
recommended that a **revocation certificate** be created and safely stored
|
|
|
|
|
in multiple locations so that the master keypair can be revoked in the
|
|
|
|
|
(exceedingly unlikely) event that it is ever compromised.
|
|
|
|
|
|
|
|
|
|
* `ssb` (secret subkey)
|
|
|
|
|
|
|
|
|
|
Depending on your needs, you may wish to create two different subkeys: one
|
|
|
|
|
for **signing (S)** and one for **encryption (E)**. You may also wish to
|
|
|
|
|
give these subkeys reasonable expiration dates (e.g., one year). Once these
|
|
|
|
|
keys expire, it is up to you whether to *renew* these keys by extending the
|
|
|
|
|
expiration dates or to create *new* subkeys when the existing set expires.
|
|
|
|
|
|
|
|
|
|
On the one hand, an adversary who obtains any existing encryption subkey
|
|
|
|
|
(for example) will be able to use it in order to decrypt all emails (for
|
|
|
|
|
example) which were encrypted to that subkey. If the same subkey were to
|
|
|
|
|
continue to be used--and its expiration date continually extended--only
|
|
|
|
|
that one key would need to be stolen (e.g., as a result of the `work-gpg`
|
|
|
|
|
VM being compromised; see below) in order to decrypt *all* of the user's
|
|
|
|
|
emails. If, on the other hand, each encryption subkey is used for at most
|
|
|
|
|
approximately one year, then an adversary who obtains the secret subkey will
|
|
|
|
|
be capable of decrypting at most approximately one year's worth of emails.
|
|
|
|
|
|
|
|
|
|
On the other hand, creating a new signing subkey each year without
|
|
|
|
|
renewing (i.e., extending the expiration dates of) existing signing
|
|
|
|
|
subkeys would mean that all of your old signatures would eventually
|
|
|
|
|
read as "EXPIRED" whenever someone attempts to verify them. This can be
|
|
|
|
|
problematic, since there is no consensus on how expired signatures should
|
|
|
|
|
be handled. Generally, digital signatures are intended to last forever,
|
|
|
|
|
so this is a strong reason against regularly retiring one's signing subkeys.
|
|
|
|
|
|
|
|
|
|
* `pub` (public key)
|
|
|
|
|
|
|
|
|
|
This is the complement of the master secret key. It can be uploaded to
|
|
|
|
|
keyservers (or otherwise publicly distributed) and may be signed by others.
|
|
|
|
|
|
|
|
|
|
* `vault`
|
|
|
|
|
|
|
|
|
|
This is a network-isolated VM. The initial master keypair and
|
|
|
|
|
subkeys are generated in this VM. The master secret key *never*
|
|
|
|
|
leaves this VM under *any* circumstances. No files or text is *ever*
|
|
|
|
|
[copied](/doc/CopyingFiles#on-inter-domain-file-copy-security) or
|
|
|
|
|
[pasted](/doc/CopyPaste#on-copypaste-security) into this VM under *any*
|
|
|
|
|
circumstances.
|
|
|
|
|
|
|
|
|
|
* `work-gpg`
|
|
|
|
|
|
|
|
|
|
This is a network-isolated VM. This VM is used *only* as the
|
|
|
|
|
GPG backend for `work-email`. The secret subkeys (but *not*
|
|
|
|
|
the master secret key) are [copied](/doc/CopyingFiles) from the
|
|
|
|
|
`vault` VM to this VM. Files from less trusted VMs are *never*
|
|
|
|
|
[copied](/doc/CopyingFiles#on-inter-domain-file-copy-security) into this
|
|
|
|
|
VM under *any* circumstances.
|
|
|
|
|
|
|
|
|
|
* `work-email`
|
|
|
|
|
|
|
|
|
|
This VM has access to the mail server. It accesses the `work-gpg` VM via
|
|
|
|
|
the Split GPG protocol. The public key may be stored in this VM so that
|
|
|
|
|
it can be attached to emails and for other such purposes.
|
2014-08-03 06:15:09 -04:00
|
|
|
|
|
2015-09-22 13:29:54 -04:00
|
|
|
|
### Security Benefits ###
|
2014-08-03 00:30:42 -04:00
|
|
|
|
|
2015-09-22 14:00:52 -04:00
|
|
|
|
In the standard Split GPG setup, there are at least two ways in
|
|
|
|
|
which the `work-gpg` VM might be compromised. First, an attacker
|
|
|
|
|
who is capable of exploiting a hypothetical bug in `work-email`'s
|
|
|
|
|
[MUA](https://en.wikipedia.org/wiki/Mail_user_agent) could gain control of
|
|
|
|
|
the `work-email` VM and send a malformed request which exploits a hypothetical
|
|
|
|
|
bug in the GPG backend (running in the `work-gpg` VM), giving the attacker
|
|
|
|
|
control of the `work-gpg` VM. Second, a malicious public key file which is
|
|
|
|
|
imported into the `work-gpg` VM might exploit a hypothetical bug in the GPG
|
|
|
|
|
backend which is running there, again giving the attacker control of the
|
|
|
|
|
`work-gpg` VM. In either case, such an attacker might then be able to leak
|
|
|
|
|
both the master secret key and its passphrase (if any is used, it would
|
|
|
|
|
regularly be input in the work-gpg VM and therefore easily obtained by an
|
|
|
|
|
attacker who controls this VM) back to the `work-email` VM or to another VM
|
|
|
|
|
(e.g., the `netvm`, which is always untrusted by default) via the Split GPG
|
|
|
|
|
protocol or other [covert channels](/doc/DataLeaks). Once the master secret
|
|
|
|
|
key is in the `work-email` VM, the attacker could simply email it to himself
|
|
|
|
|
(or to the world).
|
|
|
|
|
|
|
|
|
|
In the alternative setup described in this section (i.e., the subkey
|
|
|
|
|
setup), even an attacker who manages to gain access to the `work-gpg` VM
|
|
|
|
|
will not be able to obtain the user's master secret key since it is simply
|
|
|
|
|
not there. Rather, the master secret key remains in the `vault` VM, which
|
|
|
|
|
is extremely unlikely to be compromised, since nothing is ever copied or
|
|
|
|
|
transferred into it.<sup>\*</sup> The attacker might nonetheless be able to
|
|
|
|
|
leak the secret subkeys from the `work-gpg` VM in the manner described above,
|
|
|
|
|
but even if this is successful, the secure master secret key can simply be
|
|
|
|
|
used to revoke the compromised subkeys and to issue new subkeys in their
|
|
|
|
|
place. (This is significantly less devastating than having to create a new
|
|
|
|
|
*master* keypair.)
|
|
|
|
|
|
|
|
|
|
<sup>\*</sup>In order to gain access to the `vault` VM, the attacker
|
|
|
|
|
would require the use of, e.g., a general Xen VM escape exploit
|
|
|
|
|
or a [signed, compromised package which is already installed in the
|
|
|
|
|
TemplateVM](/doc/SoftwareUpdateVM#notes-on-trusting-your-template-vms)
|
|
|
|
|
upon which the `vault` VM is based.
|
2015-09-22 13:29:54 -04:00
|
|
|
|
|
|
|
|
|
### Subkey Tutorials and Discussions ###
|
2014-08-03 00:30:42 -04:00
|
|
|
|
|
2015-09-22 14:00:52 -04:00
|
|
|
|
(Note: Although the tutorials below were not written with Qubes Split GPG
|
|
|
|
|
in mind, they can be adapted with a few commonsense adjustments. As always,
|
|
|
|
|
exercise caution and use your good judgment.)
|
2014-08-03 00:30:42 -04:00
|
|
|
|
|
|
|
|
|
- ["OpenPGP in Qubes OS" on the qubes-users mailing list](https://groups.google.com/d/topic/qubes-users/Kwfuern-R2U/discussion)
|
|
|
|
|
- ["Creating the Perfect GPG Keypair" by Alex Cabal](https://alexcabal.com/creating-the-perfect-gpg-keypair/)
|
|
|
|
|
- ["GPG Offline Master Key w/ smartcard" maintained by Abel Luck](https://gist.github.com/abeluck/3383449)
|
|
|
|
|
- ["Using GnuPG with QubesOS" by Alex](https://apapadop.wordpress.com/2013/08/21/using-gnupg-with-qubesos/)
|
|
|
|
|
|