GnuPG: 用多个sub keys保护primary key

我想到了一种保护PGP密钥长时间不换的方法. 就是利用GnuPG的一个扩展, 只导出secret sub keys而不导出primary secret key, 把这些secret sub keys放到不同的地方使用.

最开始是看了GnuPG的FAQ发现的, 后来发现原来还是有很多先人呀. 🙂

参考:

  How can I use GnuPG in an automated environment?
    http://www.gnupg.org/documentation/faqs.en.html#q4.14

  Using multiple subkeys in GPG
    http://fortytwo.ch/gpg/subkeys

  using various subkeys [HOWTO]
    http://lists.gnupg.org/pipermail/gnupg-users/2002-August/014780.html

  PGP: Public Key Servers
    http://www.rossde.com/PGP/pgp_keyserv.html

这种方法的特点:

  • 可以满足日常的加密, 解密, 签名的需要.
  • 可以在不同地方设置不同的密码, 从而提供不同的保密级别.
  • 只导出secret sub keys可以保护primary key的安全.
  • 只有primary key才能签署其他人的密钥, 这样做使得primary key用起来麻烦一些, 强迫我们三思而后行.

但是,

  • 比较老的PGP keyserver都不支持多个sub keys, 上传的key会被截断. 可以用别的keyserver, 或者直接用文本传.

运行PGP Key Server 0.9.6的服务器, 如MIT的, 就不接受多个sub keys. 而运行SKS 1.0.10的服务器, 如Ubuntu的, 就支持多个sub keys.

还有一个就是密钥生成过程中的存储问题. 因为密钥的生成过程是要保存在外存上的, 即使随后删除也有可能会被离线恢复. 我想了下面几种办法.

一个就是在生成密钥并导出之后, 用Sysinternals的sdelete工具对中间文件进行安全删除. 但是如果假设文件系统一般会为改写的文件重新分配空间, 所以感觉这不是一种很安全的办法.

还有一个就是用NTFS提供的EFS机制, 不过如果对Windows系统保护不够强, 还是形同虚设. 具体做法是, 先将AppData里的gnupg目录设置为加密, 然后再进行创建密钥等操作, 保存到硬盘上的数据起码就不是明文了. 不过通过一些工具盘应该还是能通过SAM找到EFS密钥的.

虽然有顾虑, 其实上面两种办法已经给破解加大了不少难度.

最后, 如果能在一张UDF的CD-R上操作, 然后直接妥善保存这张CD-R, 我想这应该是最安全的了.

Windows Vista本身就支持UDF的写入. Windows XP需要第三方的UDF写入支持, 如

  • Sonic Drive Letter Access
  • Roxio Drag-to-Disc (Adaptec DirectCD)
  • Nero InCD

美中不足的是这些UDF写入方式看起来也不甚兼容.

假设已经以UDF格式化好的CD-R在F:, 那么设置GNUPGHOME环境变量就可以让GnuPG
在光盘上工作了.

C> F:
F> set GNUPGHOME=F:GnuPG

============================================================

首先创建primary key. 原则上, 作为自己身份的证明, 应该是永远不过期的. passphrase则应足够保险, 自己好记的, 别人不容易猜出的, 允许空格, 最好有数字符号, 不少于20个字符.

F> gpg --gen-key

Please select what kind of key you want:
   (1) DSA and Elgamal (default)
   (2) DSA (sign only)
   (5) RSA (sign only)
Your selection? 1
What keysize do you want? (2048)
Requested keysize is 2048 bits
Key is valid for? (0)
Key does not expire at all

Real name: Quan Qiu
Email address: jackqq@gmail.com
Comment: Testing GnuPG
You selected this USER-ID:
    "Quan Qiu (Testing GnuPG) <jackqq@gmail.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:
Repeat passphrase:
……………+++++

gpg: key 9061D35B 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
pub   1024D/9061D35B 2008-06-21
      Key fingerprint = 04EE 15CC 1DE5 1115 8F8A  F0F0 6301 CEEF 9061 D35B
uid                  Quan Qiu (Testing GnuPG) <jackqq@gmail.com>
sub   2048g/11DD7B4D 2008-06-21

============================================================

别忘了生成一个密钥撤销证书. 这个一定要妥善保管, 不能泄露.

F> gpg --output revokecert.txt --gen-revoke jackqq

sec  1024D/9061D35B 2008-06-21 Quan Qiu (Testing GnuPG) <jackqq@gmail.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? 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: "Quan Qiu (Testing GnuPG) <jackqq@gmail.com>"
1024-bit DSA key, ID 9061D35B, created 2008-06-21

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!

============================================================

下面为各种用途创建sub keys. 比如, 在家里, 工作场所和便携电脑上的, 用于签名和加密的不同密钥. 这些sub keys可以适当设置有效期限.

F> gpg --edit jackqq

Secret key is available.

pub  1024D/9061D35B  created: 2008-06-21  expires: never       usage: SC
                     trust: ultimate      validity: ultimate
sub  2048g/11DD7B4D  created: 2008-06-21  expires: never       usage: E
[ultimate] (1). Quan Qiu (Testing GnuPG) <jackqq@gmail.com>

Command> addkey
Please select what kind of key you want:
   (2) DSA (sign only)
   (4) Elgamal (encrypt only)
   (5) RSA (sign only)
   (6) RSA (encrypt only)
Your selection? 2
DSA keypair will have 1024 bits.
Key is valid for? (0) 3m
………………………….+++++

pub  1024D/9061D35B  created: 2008-06-21  expires: never       usage: SC
                     trust: ultimate      validity: ultimate
sub  2048g/11DD7B4D  created: 2008-06-21  expires: never       usage: E
sub  1024D/5B0E7472  created: 2008-06-21  expires: 2008-09-19  usage: S
[ultimate] (1). Quan Qiu (Testing GnuPG) <jackqq@gmail.com>

Command> addkey
Please select what kind of key you want:
   (2) DSA (sign only)
   (4) Elgamal (encrypt only)
   (5) RSA (sign only)
   (6) RSA (encrypt only)
Your selection? 4
What keysize do you want? (2048)
Key is valid for? (0) 3m
………………………+++++^^^

pub  1024D/9061D35B  created: 2008-06-21  expires: never       usage: SC
                     trust: ultimate      validity: ultimate
sub  2048g/11DD7B4D  created: 2008-06-21  expires: never       usage: E
sub  1024D/5B0E7472  created: 2008-06-21  expires: 2008-09-19  usage: S
sub  2048g/CB36A1C8  created: 2008-06-21  expires: 2008-09-19  usage: E
[ultimate] (1). Quan Qiu (Testing GnuPG) <jackqq@gmail.com>

Command>quit
Save changes? (y/N) y

============================================================

然后就可以为各种用途导出钥匙链了. 用–export-secret-subkeys选项导出的私钥钥匙链里的primary key是无效的, 从而保证了它的安全. 在修改不同用途的钥匙链时, 可以用passwd命令设置不同的passphrase, 然后去掉多余的 sub keys.

F> mkdir home office laptop
F> cd office
F> gpg --export-secret-subkeys --no-comments > secring.gpg
F> copy %GNUPGHOME%pubring.gpg .
F> gpg --homedir . --edit jackqq

Secret key is available.

gpg: ./trustdb.gpg: trustdb created
pub  1024D/9061D35B  created: 2008-06-21  expires: never       usage: SC
                     trust: unknown       validity: unknown
sub  2048g/11DD7B4D  created: 2008-06-21  expires: never       usage: E
sub  1024D/5B0E7472  created: 2008-06-21  expires: 2008-09-19  usage: S
sub  2048g/CB36A1C8  created: 2008-06-21  expires: 2008-09-19  usage: E
sub  1024D/6C06E245  created: 2008-06-21  expires: 2008-12-18  usage: S
sub  2048g/5CBC7406  created: 2008-06-21  expires: 2008-12-18  usage: E
sub  1024D/903CF7E7  created: 2008-06-21  expires: 2009-06-21  usage: S
sub  2048g/084E750C  created: 2008-06-21  expires: 2009-06-21  usage: E
[unknown] (1). Quan Qiu (Testing GnuPG) <jackqq@gmail.com>

Command> addkey
Secret parts of primary key are not available.
gpg: Key generation failed: secret key not available

Command> passwd
Secret parts of primary key are not available.

You need a passphrase to unlock the secret key for
user: "Quan Qiu (Testing GnuPG) <jackqq@gmail.com>"
2048-bit ELG-E key, ID 11DD7B4D, created 2008-06-21

Enter passphrase:
Enter the new passphrase for this secret key.
Enter passphrase:
Repeat passphrase:

Command> key 1
Command> key 5
Command> key 6
Command> key 7
Command> key 8

pub  1024D/9061D35B  created: 2008-06-21  expires: never       usage: SC
                     trust: unknown       validity: unknown
sub* 2048g/11DD7B4D  created: 2008-06-21  expires: never       usage: E
sub  1024D/5B0E7472  created: 2008-06-21  expires: 2008-09-19  usage: S
sub  2048g/CB36A1C8  created: 2008-06-21  expires: 2008-09-19  usage: E
sub* 1024D/6C06E245  created: 2008-06-21  expires: 2008-12-18  usage: S
sub* 2048g/5CBC7406  created: 2008-06-21  expires: 2008-12-18  usage: E
sub* 1024D/903CF7E7  created: 2008-06-21  expires: 2009-06-21  usage: S
sub* 2048g/084E750C  created: 2008-06-21  expires: 2009-06-21  usage: E
[unknown] (1). Quan Qiu (Testing GnuPG) <jackqq@gmail.com>

Command> delkey
Do you really want to delete the selected keys? (y/N) y

pub  1024D/9061D35B  created: 2008-06-21  expires: never       usage: SC
                     trust: unknown       validity: unknown
sub  1024D/5B0E7472  created: 2008-06-21  expires: 2008-09-19  usage: S
sub  2048g/CB36A1C8  created: 2008-06-21  expires: 2008-09-19  usage: E
[unknown] (1). Quan Qiu (Testing GnuPG) <jackqq@gmail.com>

Command> quit
Save changes? (y/N) y

============================================================

别忘了发布公钥.

F> gpg --keyserver keyserver.ubuntu.com --send-keys 9061D35B

============================================================

把这个私钥钥匙链, 也就是secring.gpg, 复制到相应的地方导入即可.

C> set GNUPGHOME=
C> gpg --import F:officesecring.gpg

更新一下公钥, 因为私钥中没有保存revuid的信息.

C> gpg --keyserver keyserver.ubuntu.com --refresh-keys

如果还没信任过这个key, 现在可以设置信任.

C> gpg --edit-key jackqq

Command> trust
pub  1024D/9061D35B  created: 2008-06-21  expires: never       usage: SC
                     trust: unknown       validity: unknown
sub  1024D/5B0E7472  created: 2008-06-21  expires: 2008-09-19  usage: S
sub  2048g/CB36A1C8  created: 2008-06-21  expires: 2008-09-19  usage: E
[ unknown] (1). Quan Qiu (Testing GnuPG) <jackqq@gmail.com>

Please decide how far you trust this user to correctly verify other users’ keys
(by looking at passports, checking fingerprints from different sources, etc.)

  1 = I don’t know or won’t say
  2 = I do NOT trust
  3 = I trust marginally
  4 = I trust fully
  5 = I trust ultimately
  m = back to the main menu

Your decision? 5
Do you really want to set this key to ultimate trust? (y/N) y

pub  1024D/9061D35B  created: 2008-06-21  expires: never       usage: SC
                     trust: ultimate      validity: unknown
sub  1024D/5B0E7472  created: 2008-06-21  expires: 2008-09-19  usage: S
sub  2048g/CB36A1C8  created: 2008-06-21  expires: 2008-09-19  usage: E
[ unknown] (1). Quan Qiu (Testing GnuPG) <jackqq@gmail.com>
Please note that the shown key validity is not necessarily correct
unless you restart the program.

Command> quit

About QIU Quan

A sysadmin and casual developer.
此条目发表在desktop, hacking分类目录。将固定链接加入收藏夹。

留下评论