在本系列的第一篇文章中,我解释了如何使用GPG密钥对SSH连接进行身份验证。 如果您像我一样,则已经有一个或多个现有的SSH密钥。 而且,如果您像我一样,也不必登录到用于更新authorized_keys文件的每台服务器。 一种解决方法是将现有的SSH密钥导入GPG密钥。 这将消除对私钥文件的需求。 这样做使我可以消除其他九个关键文件,从而大大减少了备份/隐私足迹。
导入现有的SSH密钥
要添加密钥,您需要将密钥格式从SSH使用的隐私增强邮件(PEM)编码格式转换为OpenPGP格式的证书。 Monkeysphere项目提供了一个实用程序pem2openpgp ,可以为您完成此任务。
不幸的是,使这个新添加的键成为子键不是一个一步的过程。 需要更长的过程,因为没有干净的方法可以删除仅包含SSH密钥的密钥环中的GPG密钥。 密钥由keygrip标识和操作,并且密钥的keygrip相同,无论是子密钥还是独立密钥。 值得庆幸的是,您只需要使用私钥,因为您可以在最后重新生成公钥。
另外,如果您拥有更新样式的OpenSSH密钥,则需要执行一些额外的步骤将其转换为pem2openpgp可以读取的内容。 不幸的是,从0.41版开始,Monkeysphere无法读取较新样式的OpenSSH密钥。 (如果私钥文件的第一行是: ----- BEGIN OPENSSH PRIVATE KEY -----,则您的密钥是较新的样式密钥。如果您的密钥开头为: ----- BEGIN RSA PRIVATE KEY- ---- ,则您具有PEM编码格式。)
要导入较新的密钥,您需要将其转换为旧格式。 这是通过使用ssh-keygen并利用其以多种密钥格式编写的能力来完成的。 您可以通过更改密钥上的密码来触发转换。 在这种情况下,您无需更改密码,因此,如果愿意,可以随时重用现有密码。
下面的工作流程将引导我们完成这些步骤。
- 如果您具有较新样式的OpenSSH密钥,请使用ssh-keygen实用程序对其进行转换。 您可以使用此实用程序更改密码(如果需要),并强制以旧格式重写密钥。 ssh-keygen的典型用法与此用法之间的唯一区别是添加了-m以更改密钥的格式。
$ ssh-keygen -p -m PEM -f <private-key-file>
- 备份您现有的GPG密钥。
$ gpg2 -a --export-secret-keys 96F33EA7F4E0F7051D75FC208715AF32191DB135 > my_gpg_key.asc
- 在新的密钥环中,导入您现有的GPG密钥。 $ mkdir temp_gpg
$ chmod go-rwx temp_gpg/
$ gpg2 --homedir temp_gpg --import my_gpg_key.asc
gpg: key 8715AF32191DB135: public key "Brian Exelbierd" imported
gpg: key 8715AF32191DB135: secret key imported
# Optionally, verify the import
$ gpg2 -K --homedir temp_gpg/
/home/bexelbie/temp_gpg/pubring.kbx
--------------------------------
sec rsa2048 2019-03-21 [SC] [expires: 2021-03-20]
96F33EA7F4E0F7051D75FC208715AF32191DB135
uid [ unknown] Brian Exelbierd
ssb rsa2048 2019-03-21 [E] [expires: 2021-03-20]
ssb rsa2048 2019-03-21 [A] - 将SSH密钥作为新的独立GPG密钥导入。 # get the software
$ dnf install -y monkeysphere
# temporary_id is a temporary identifier required by GPG
$ pem2openpgp temporary_id < .ssh/my_fancy_key | gpg2 --import --homedir temp_gpg/
Enter PEM pass phrase:
gpg: key 66091F2C70AF02A9: public key "temporary_id" imported
gpg: key 66091F2C70AF02A9: secret key imported
gpg: Total number processed: 1
gpg: imported: 1
gpg: secret keys read: 1
gpg: secret keys imported: 1
# verify the key loaded and get the keygrip of the new GPG key and the hash of your GPG key
$ gpg2 -K --with-keygrip --homedir temp_gpg/
/home/bexelbie/temp_gpg/pubring.kbx
--------------------------------
sec rsa2048 2019-03-21 [SC] [expires: 2021-03-20]
96F33EA7F4E0F7051D75FC208715AF32191DB135
Keygrip = 90E08830BC1AAD225E657AD4FBE638B3D8E50C9E
uid [ unknown] Brian Exelbierd
ssb rsa2048 2019-03-21 [E] [expires: 2021-03-20]
Keygrip = 5FA04ABEBFBC5089E50EDEB43198B4895BCA2136
ssb rsa2048 2019-03-21 [A]
Keygrip = 7710BA0643CC022B92544181FF2EAC2A290CDC0E
sec rsa2048 2019-03-23 [C]
D4F6B35B52B96A092FB8F418A41A06197749FBA4
Keygrip = 1F824257B107D9E3371B9A4957751D78FC8BB190
uid [ unknown] temporary_id
# We can remove monkeysphere unless you need it for other reasons
$ dnf remove -y monkeysphere - 将SSH密钥添加为GPG密钥的子密钥。
请注意,现在有两个身份验证子项。$ gpg2 --homedir temp_gpg --expert --edit-key 96F33EA7F4E0F7051D75FC208715AF32191DB135
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)
(7) DSA (set your own capabilities)
(8) RSA (set your own capabilities)
(10) ECC (sign only)
(11) ECC (set your own capabilities)
(12) ECC (encrypt only)
(13) Existing key
Your selection? 13
Enter the keygrip: 1F824257B107D9E3371B9A4957751D78FC8BB190
Possible actions for a RSA key: Sign Encrypt Authenticate
Current allowed actions: Sign Encrypt
(S) Toggle the sign capability
(E) Toggle the encrypt capability
(A) Toggle the authenticate capability
(Q) Finished
Your selection? s
Your selection? e
Your selection? a
Possible actions for a RSA key: Sign Encrypt Authenticate
Current allowed actions: Authenticate
(S) Toggle the sign capability
(E) Toggle the encrypt capability
(A) Toggle the authenticate capability
(Q) Finished
Your selection? q
Please specify how long the key should be valid.
Key is valid for? (0)
Key does not expire at all
Is this correct? (y/N) y
Really create? (y/N) y
sec rsa2048/8715AF32191DB135
created: 2019-03-21 expires: 2021-03-20 usage: SC
trust: unknown validity: unknown
ssb rsa2048/150F16909B9AA603
created: 2019-03-21 expires: 2021-03-20 usage: E
ssb rsa2048/17E7403F18CB1123
created: 2019-03-21 expires: never usage: A
ssb rsa2048/4A9EE7790817C411
created: 2019-03-23 expires: never usage: A
[ unknown] (1). Brian Exelbierd
gpg> quit
Save changes? (y/N) y - 使用新的子项导出现有的GPG项。
$ gpg2 --homedir temp_gpg -a --export-secret-keys 96F33EA7F4E0F7051D75FC208715AF32191DB135 > my_new_gpg_key.asc
- 将具有新的子项的现有GPG项导入到惯用的密钥环中(仅子项会导入)。 $ gpg2 --import my_new_gpg_key.asc
gpg: key 8715AF32191DB135: "Brian Exelbierd" 1 new signature
gpg: key 8715AF32191DB135: "Brian Exelbierd" 1 new subkey
gpg: key 8715AF32191DB135: secret key imported
gpg: Total number processed: 1
gpg: new subkeys: 1
gpg: new signatures: 1
gpg: secret keys read: 1
gpg: secret keys imported: 1
gpg: secret keys unchanged: 1
# verify the input and get the keygrip (it should be the same)
$ gpg2 -K --with-keygrip
/home/bexelbie/.gnupg/pubring.kbx
------------------------------
sec rsa2048 2019-03-21 [SC] [expires: 2021-03-20]
96F33EA7F4E0F7051D75FC208715AF32191DB135
Keygrip = 90E08830BC1AAD225E657AD4FBE638B3D8E50C9E
uid [ultimate] Brian Exelbierd
ssb rsa2048 2019-03-21 [E] [expires: 2021-03-20]
Keygrip = 5FA04ABEBFBC5089E50EDEB43198B4895BCA2136
ssb rsa2048 2019-03-21 [A]
Keygrip = 7710BA0643CC022B92544181FF2EAC2A290CDC0E
ssb rsa2048 2019-03-23 [A]
Keygrip = 1F824257B107D9E3371B9A4957751D78FC8BB190 - (可选)您可能希望预先指定此密钥将用于SSH。 这意味着您将不必使用ssh-add来加载密钥。 为此,请在〜/ .gnupg / sshcontrol文件中指定键。 此文件中的条目是按键。 ~/.gnupg/sshcontrol file. The entries in this file are key grips
# Add the new keygrip to your sshcontrol file
$ echo 1F824257B107D9E3371B9A4957751D78FC8BB190 >> ~/.gnupg/sshcontrol
成功!
现在,您可以删除旧的SSH私钥文件。 当您尝试通过SSH进入相应的服务器时,系统会提示您解锁GPG密钥(最好输入密码!),然后gpg-agent将代替ssh-agent提供身份验证。 您需要安全备份的文件较少,密钥管理更加轻松。 如果您需要新密钥,则可以按照上一篇文章中的说明创建更多身份验证子密钥。 如果您正在处理的项目结束,则始终可以删除最终使用的所有其他子项。
在第三篇也是最后一篇文章中,我将分享一些管理多个身份验证子项/ SSH密钥的技巧。 一旦拥有两个或三个以上,它将变得更加复杂。
翻译自: https://opensource.com/article/19/4/gpg-subkeys-ssh-multiples