我正在尝试将导入的 ssh 密钥附加到现有主密钥。导入的 ssh 密钥位于 ~/.gnupg/private-keys-v1.d/ 中,可通过 gpg-agent 使用。当我手动将其关联到主密钥时,它运行良好。我正在寻找一种通过 bash 脚本自动化该过程的方法。
对于此示例:
- AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 是主键的指纹
- BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB 是导入的 ssh 密钥的 keygrip,用于关联到主密钥
手动执行(有效):
bob@computer:~$ gpg --expert --edit-key AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
gpg (GnuPG) 2.2.12; Copyright (C) 2018 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.
sec rsa2048/AAAAAAAAAAAAAAAA
created: 2020-04-01 expires: never usage: SCEA
trust: ultimate validity: ultimate
[ultimate] (1). My name <[email protected]>
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: BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB
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
Possible actions for a RSA key: Sign Encrypt Authenticate
Current allowed actions: Encrypt
(S) Toggle the sign capability
(E) Toggle the encrypt capability
(A) Toggle the authenticate capability
(Q) Finished
Your selection? e
Possible actions for a RSA key: Sign Encrypt Authenticate
Current allowed actions:
(S) Toggle the sign capability
(E) Toggle the encrypt capability
(A) Toggle the authenticate capability
(Q) Finished
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.
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) 0
Key does not expire at all
Is this correct? (y/N) y
Really create? (y/N) y
sec rsa2048/AAAAAAAAAAAAAAAA
created: 2020-04-01 expires: never usage: SCEA
trust: ultimate validity: ultimate
ssb rsa4096/8022F3DA9BFC5AC3
created: 2020-04-01 expires: never usage: A
[ultimate] (1). My name <[email protected]>
gpg> save
bob@computer:~$
我们可以看到子键已成功与主键关联。这就是指纹为 8022F3DA9BFC5AC3 的子键。
现在我将向您展示我尝试通过 bash 脚本自动执行此操作的两种方法。
首先,我尝试使用参数--command-fd(它不起作用):
{
echo addkey
echo 13 # Existing key
echo BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB
echo
echo S #
echo E #
echo A #
echo Q #
echo 0 # key does not expire
echo save
} | gpg --expert --command-fd=0 --status-fd=1 --pinentry-mode=loopback --edit-key AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
然后我尝试使用参数--command-file(它不起作用):
cat > /tmp/cmd << EOF
addkey
13
BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB
S
E
A
Q
0
save
EOF
gpg --expert --command-file=/tmp/cmd --status-fd=1 --pinentry-mode=loopback --edit-key AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
这两种方法都不起作用。总是出现提示“输入 keygrip:”。我真的想避免在此过程中进行用户交互。我尝试了许多流重定向,如管道(使用命令 yes)、Here Documents、Here Strings、进程替换等。似乎没有任何东西可以在没有人为干预的情况下注入 keygrip。
答案1
感谢一位同事建议我使用以下解决方案预计工具:
expect << EOF
spawn bash -c "{ echo addkey; echo 13; echo S; echo E; echo A; echo Q; echo 0; echo save; } | gpg --expert --command-fd=0 --status-fd=1 --pinentry-mode=loopback --edit-key AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
expect "Enter the keygrip: " { send "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB\r" }
expect eof
EOF
即使这个解决方案有效,我也不完全满意,原因如下:
- 它真的很丑
- 需要安装预计,我只想要一个 gpg+bash 解决方案
- 如果发生错误,可能会产生调试问题
因此,如果有人有更好的解决方案,我仍然感兴趣。
答案2
对于此操作,我怀疑使用密钥指纹是不够的,而是需要要点的子密钥您想要导入的。
以下是我的做法:
gpg --list-keys --with-keygrip AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
找到所需的子项并复制要点值略低于(40 个十六进制字符)。将此值与当前值进行比较。一定有一些特定于上下文的东西导致无人值守执行失败,尽管我现在无法准确指出原因。我不认为这与 GPG 代理有关,但不确定。
参考: