实际上是可以做到的。
atom.smasher.org/gpg/gpg-migrate.txt上的说明现已过时。
试试这个。与往常一样,进行备份,因为它真的很容易搞砸。
所以这些是你的“旧”钥匙:
$ gpg -K
----------------------------------
sec 2048R/712A2BBD 2013-01-29
uid Test Key 1
ssb 2048R/F0B63FDA 2013-01-29
sec 2048R/72838B89 2013-01-29
uid Test Key 2
ssb 2048R/A19F06EC 2013-01-29
sec 2048D/AC349218 2013-03-21
uid Test Key 3
ssb 2048g/179E9F47 2013-03-21
并且您创建了一个没有子密钥的新“主密钥”:
sec 4096R/CB577A43 2013-03-21
uid Master Key
为简单起见,我将仅使用您的第一个“旧”键来排练该过程:
sec 2048R/712A2BBD 2013-01-29
uid Test Key 1
ssb 2048R/F0B63FDA 2013-01-29
使用相同的过程,您可以添加所有这些。我建议您同时添加所有这些,因为每次您破坏密钥然后重新组装它们时,您都必须重新创建绑定签名,这很痛苦。
1. 使用 gpgsplit 将“旧”密钥拆分为其组成数据包。
$ gpg --export-secret-keys 712A2BBD | gpgsplit -vp 712A2BBD_
现在查看它创建的文件:
$ ls
----------------------------------
712A2BBD_000001-005.secret_key
712A2BBD_000002-013.user_id
712A2BBD_000003-002.sig
712A2BBD_000004-007.secret_subkey
712A2BBD_000005-002.sig
第一个文件“712A2BBD_000001-005.secret_key”包含“旧”密钥“712A2BBD”的主私钥(数据包类型标签 5,因此是“005”)的数据包。(您将需要这个,但如果您想将其迁移到新的“主密钥”中,则需要将其转换为子密钥。在使用 GPG 上的标准设置生成的密钥中,主私钥通常具有使用标志“S”用于签名和“C”用于证明,并且没有“E”用于加密,这通常是使用“E”子密钥生成密钥的原因。但是,由于我们使用的程序,最终主密钥是变成一个子密钥并迁移到您的新“主密钥”,它将启用所有使用标志(“SCEA”)。
第二个文件“712A2BBD_000002-013.user_id”是用户 ID 的数据包(数据包类型标签 13)。(你不需要这个)。
第三个文件“712A2BBD_000003-002.sig”是这些数据包的绑定签名(数据包类型标签 2)。(你不需要这个)。
第四个文件是秘密子密钥 (F0B63FDA) 的数据包(数据包类型标签 7)。(您将需要这个。通常,像这样的子密钥具有“E”使用标志,这意味着它仅用于加密。但是,在将其导入新的“主密钥”的过程中,它将获取所有使用标志,(“SCEA”),这可能不是一件好事。)
第五个文件“712A2BBD_000005-002.sig”是子密钥的绑定签名(数据包类型标签 2)。你不会需要它。
保存您需要的两个文件并删除其他文件。
2. 将主键(712A2BBD)更改为子键。
您无需对子密钥 (F0B63FDA) 执行任何操作即可将其迁移到新的“主密钥”,但需要更改旧密钥的主密钥 (712A2BBD) 才能使其正常工作。
在能够进行十六进制或二进制编辑的编辑器中打开主键“712A2BBD_000001-005.secret_key”。我用ghex:
$ ghex 712A2BBD_000001-005.secret_key
如果您使用的是十六进制编辑器,则第一个字节将为“95”。将其更改为“9D”。
如果您使用的是二进制编辑器,则第一个字节将为“10010101”。将其更改为“10011101”。
保存它,然后使用 pgpdump 来查看是否成功将其更改为子项。如果成功,您将看到以下输出:
$ pgpdump 712A2BBD_000001-005.secret_key | head -1
-----------------
Old: Secret Subkey Packet(tag 7)(1836 bytes)
3. 为您要添加的每个子项添加一个“虚拟”子项到您的新“主密钥” 。
就像在atom.smasher.org上的教程一样,您需要在“主密钥”上创建新的“虚拟”子密钥,以确保您在主密钥上有可以容纳的键绑定签名(至少在开始时)迁移子项。
可以将其视为为旧子项创建“插槽”以插入其中。您将需要与要添加的键一样多的插槽。
在本示例中,我们将创建两个虚拟子键,但如果您想添加您在原始帖子中列出的所有键,则需要创建六个。
$ gpg --expert --edit-key CB577A43
----------------------------------------
gpg (GnuPG) 1.4.12; Copyright (C) 2012 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/CB577A43 created: 2013-03-21 expires: never usage: SC
trust: unknown validity: unknown
gpg>addkey
确保在通过子密钥生成向导(处于专家模式,感谢上面的 --expert 选项)时,当您生成新的“虚拟”子密钥时,它是相同的......
- 关键强度(2048、4096 等)
- 类型(DSA、RSA、elgamal)
- 用法(加密、签名)
...作为您打算添加到该“插槽”中的子项。
由于我们添加了两个子键,因此我们在“主键”上添加了两个新的“虚拟”子键。保存并退出:
pub 4096R/CB577A43 created: 2013-03-21 expires: never usage: SC
trust: unknown validity: unknown
sub 2048R/AAAAAAAA created: 2014-01-01 expires: never usage: S
sub 2048R/BBBBBBBB created: 2014-01-01 expires: never usage: E
gpg> save
4. 将新的“主密钥”连同它的新子密钥拆分成它的组成数据包。
$ gpg --export-secret-keys CB577A43 | gpgsplit -vp CB577A43_
您最终应该得到以下内容:
$ ls
----------------
CB577A43_000001-005.secret_key
CB577A43_000002-013.user_id
CB577A43_000003-002.sig
CB577A43_000004-007.secret_subkey
**CB577A43_000005-002.sig**
CB577A43_000006-007.secret_subkey
**CB577A43_000007-002.sig**
第五个和第七个文件(我放在**s 中的那些)是您生成“虚拟子密钥”时生成的子密钥绑定签名包。你会需要这些。
第四个和第六个文件是实际的“虚拟子密钥”数据包。现在可以安全地删除它们(您应该删除的唯一文件。)
$ rm CB577A43_000004-007.secret_subkey CB577A43_000006-007.secret_subkey
5. 将迁移的“子密钥”“插入”到拆分主密钥中。
第一步和第二步给你留下了两个文件:
712A2BBD_000001-005.secret_key (the original main key of your "old key", now edited into a subkey)
712A2BBD_000004-007.secret_subkey (the original subkey of your "old key".)
现在将这些复制到具有“主密钥”的拆分成分的文件夹中,并重命名这些文件,以便它们替换我们刚刚删除的“虚拟子密钥”文件。
$ mv 712A2BBD_000001-005.secret_key CB577A43_000004-007.secret_subkey
$ mv 712A2BBD_000004-007.secret_subkey CB577A43_000006-007.secret_subkey
您应该再次拥有七个(在此示例中)文件,但文件 4 和 6 现在是您的旧密钥,已设置好并准备成为新主密钥的子密钥。
$ ls
----------------
CB577A43_000001-005.secret_key
CB577A43_000002-013.user_id
CB577A43_000003-002.sig
**CB577A43_000004-007.secret_subkey**
CB577A43_000005-002.sig
**CB577A43_000006-007.secret_subkey**
CB577A43_000007-002.sig
6. 将文件连接成私钥和公钥文件,准备导入
将文件放在一起,以便将它们连续连接成单个文件,以便以后导入。
$ cat CB577A43_000001-005.secret_key CB577A43_000002-013.user_id CB577A43_000003-002.sig CB577A43_000004-007.secret_subkey CB577A43_000005-002.sig CB577A43_000006-007.secret_subkey CB577A43_000007-002.sig > concatenated_CB577A43.secret
使用相同的命令,但将输出通过管道传输到 gpgsplit 以创建公共对应项,然后再重定向到新文件:
$ cat CB577A43_000001-005.secret_key CB577A43_000002-013.user_id CB577A43_000003-002.sig CB577A43_000004-007.secret_subkey CB577A43_000005-002.sig CB577A43_000006-007.secret_subkey CB577A43_000007-002.sig | gpgsplit --no-split --secret-to-public > concatenated_CB577A43.public
7. 备份您的密钥环,然后从您的密钥环中删除公共和私有的“旧”和“主”密钥。
$ cp -R ~/.gnupg/ ~/.gnupg_backup
$ gpg --delete-secret-and-public-keys CB577A43 712A2BBD
8. 下载并构建 gnupg-1.2.0。
最近,每当有人尝试按照atom.smasher.org上的教程进行操作时,他们遇到的问题是,对于最新版本的 gpg,一旦他们重新组装密钥并将其添加到他们的密钥环中,添加的子密钥 1) 没有用处标志,以及 2) 他们无法重置到期日期,如atom.smasher.org 教程中所建议的那样,这是创建新的有效键绑定签名的必要步骤。结果是在一个导出/导入周期后,GPG 认为密钥无效,并从私钥环中消失。
为了成功导入密钥,您必须下载并构建一个旧版本的 gnupg:不低于2002 年的版本。您已经构建了它,您将能够重置新键的到期日期,并成功地为这些键重新创建有效的键绑定。
下载旧的gnupg。
$ wget ftp://mirror.tje.me.uk/pub/mirrors/ftp.gnupg.org/gnupg/gnupg-1.2.0.tar.bz2
$ tar -xjf gnupg-1.2.0.tar.bz2
$ cd gnupg-1.2.0/
$ ./configure
$ make
导航到 g10 文件夹,其中包含您新构建的 gpg 二进制文件
$ cd g10
为了使用这个二进制文件,而不是更新的 gpg 系统范围的构建,您必须输入二进制文件的绝对路径。如果您在同一个文件夹中,请使用 ./gpg,例如:
$ ./gpg --list-keys
8. 将带有导入子密钥的新组装“主密钥”文件附加到您的公钥和私钥环中。
不要以正常方式导入密钥,因为键绑定签名不签出,导致导入的子密钥不会以正常方式导入。相反,将文件分类到您的公钥和私钥环的末尾。
$ cat concatenated_CB577A43.secret >> ~/.gnupg/secring.gpg
$ cat concatenated_CB577A43.public >> ~/.gnupg/pubring.gpg
通过使用 gnupg-1.2.0 列出键来检查他们是否已经进入那里:
$ ./gpg --list-keys
-----------------
pub 4096R/CB577A43 2013-03-21
uid Master Key
sub 2048R/712A2BBD 2013-01-29
sub 2048R/F0B63FDA 2013-01-29
9. 使用 gnupg-1.2.0 编辑密钥。
确保导航回 gnupg-1.2.0/g10 的构建文件夹,并调用构建的二进制文件来编辑新导入的新组装的主密钥,以及导入的旧子密钥:
$ ./gpg --edit-keys CB577A43
-----------------
sec 4096R/CB577A43 created: 2013-03-21 expires: never
ssb 2048R/712A2BBD created: 2013-01-29 expires: never
ssb 2048R/F0B63FDA created: 2013-01-29 expires: never
首先,重置密码。
Command> passwd
很可能您所有的旧密钥的密码都与您的新主密钥不同。如果您现在重置密码,它会依次提示您输入旧密钥的每个密码(以及子密钥 ID),当您正确输入它们时,它会要求您输入新密钥。完成此操作后,它们都将拥有相同的密码,避免以后出现奇怪的情况。
其次,重置所有密钥的到期日期。从主主密钥开始:
Command> expiry
然后按照自己的方式处理每个子项,更改每个子项的到期日期。
Command> key 1
Command> expiry
Command> key 1
Command> key 2
Command> expiry
Command> key 2
Command> key 3
等等
确保将其更改为尚未启用的值,否则不会有任何更改。您可以稍后将其更改回原始值:现在需要进行更改,以便 gpg-1.2.0 可以创建新的子键绑定签名。
一旦这一切完成保存。
Command> save
gnupg-1.2.0 将退出并保存新的键绑定签名,验证旧密钥迁移到新主密钥。
10. 现在使用标准(当前)gnupg 编辑键,看看它是否有效。
使用标准的系统范围的 gpg 版本打开相同的密钥进行编辑,看看它是否有效。如果它有效,您将看到两件事:
- 到期日期将是您刚刚在步骤 9 中更改的新到期日期,而不是原来的到期日期。
- 子项右侧的使用标志将显示“usage:SCEA”
.
$ gpg --edit-key CB577A43
--------------------------
pub 4096R/CB577A43 created: 2013-03-21 expires: [newdate] usage: SC
trust: unknown validity: unknown
sub 2048R/712A2BBD created: 2013-01-29 expires: [newdate] usage: SCEA
sub 2048R/F0B63FDA created: 2013-01-29 expires: [newdate] usage: SCEA
如果它不起作用,使用标志将为空白,并且到期日期现在将显示您在步骤 9 中所做的更改。
$ gpg --edit-key CB577A43
--------------------------
pub 4096R/CB577A43 created: 2013-03-21 expires: **never** usage: SC
trust: unknown validity: unknown
sub 2048R/712A2BBD created: 2013-01-29 expires: **never** usage:
sub 2048R/F0B63FDA created: 2013-01-29 expires: **never** usage:
最后,您需要通过一个导出/导入周期,并删除其间的键。如果它在此过程中幸存下来,则该程序有效。
$ gpg --export-secret-keys CB577A43 > CB577A43_new.secret
$ gpg --export CB577A43 > CB577A43_new.public
$ gpg --delete-secret-and-public-keys CB577A43
$ gpg --import CB577A43_new.secret CB577A43_new.public
$ gpg --edit-key CB577A43
--------------------------
pub 4096R/CB577A43 created: 2013-03-21 expires: [newdate] usage: SC
trust: unknown validity: unknown
sub 2048R/712A2BBD created: 2013-01-29 expires: [newdate] usage: SCEA
sub 2048R/F0B63FDA created: 2013-01-29 expires: [newdate] usage: SCEA
11. 最终任务。
假设它有效,您现在需要交叉验证您的子密钥,以便它们可以创建和验证签名。
$ gpg --edit-key CB577A43
从 gpg 编辑提示:
gpg> cross-certify
您还需要重置信任:
gpg> trust
最后,确保严格测试密钥,以确保它在分发之前有效。对于这些最后的步骤,我参考atom.smasher.org 教程:
检查所有到期日期和偏好。其中一些操作可能改变了您的到期日期和偏好;根据需要重新设置。
测试用于创建和验证签名以及加密/解密的所有关键组件。使用爆炸(!)强制每个(子)密钥:创建和验证签名:
$ date | gpg -u '712A2BBD!' --clearsign | gpg -v --verify
$ date | gpg -u 'F0B63FDA!' --clearsign | gpg -v --verify
加密/解密:
$ date | gpg -ear '712A2BBD!' | gpg -v --decrypt
$ date | gpg -ear 'F0B63FDA!' | gpg -v --decrypt
在本地测试出密钥后,将您的新公钥发送给一两个人并测试所有关键组件(使用所有关键组件相互发送签名/加密消息)。确保他们首先删除(从他们的钥匙圈)你的旧钥匙!并确保他们明白,在验证所有功能都可以正常工作之前,不应分发密钥!
将新密钥投入流通时,过期/撤销旧密钥可能是个好主意。包括指定新密钥 ID 的撤销注释和从密钥环中删除旧密钥的说明。
关于密钥撤销的注意事项:根据 OpenPGP 标准,由子密钥生成的撤销将被忽略,除非该子密钥已(由主密钥)指定为撤销密钥。GnuPG 似乎表现正确,但某些版本的 PGP(tm) 可能不正确。如果有人声称您的新密钥已被撤销,请从他们的密钥环中删除所有旧密钥和当前密钥:然后重新导入您当前的密钥。