我正在编写一个生成无人值守 GPG 密钥的 bash 脚本,我已经查看过GPG 的无人值守使用并惊讶地发现“目前只能处理一个子项。”
我无法找到是否有办法修改 GPG 密钥以使用可用的无人值守生成功能添加第二个子密钥,或者我是否必须自己手动添加子密钥。
我尝试使用here documents
,here strings
并创建一个每行一个输入的文件以及使用printf
类似于下面的方法:
printf 'addkey' | gpg2 --edit-key '[email protected]'
如果这些解决方案均不起作用:
balthasar@magi:~$ printf 'addkey' | gpg2 --edit-key '[email protected]'
printf 'addkey' | gpg2 --edit-key '[email protected]'
gpg (GnuPG) 2.0.26; Copyright (C) 2013 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/AB96CED4 created: 2016-12-02 expires: 2017-09-02 usage: SC
trust: ultimate validity: ultimate
sub 2048R/71804CF2 created: 2016-12-02 expires: 2017-09-02 usage: E
[ultimate] (1). test3 <[email protected]>
gpg>
我的 GPG 密钥文件
Key-Type: RSA
Key-Length: 4096
Key-Usage: sign
Subkey-Type: RSA
Subkey-Length: 2048
Subkey-Usage: encrypt
Name-Real: Foo Bar
Name-Email: [email protected]
Expire-Date: 2017-09-02
%ask-passphrase
%commit
更新:2016 年 12 月 4 日
我已经跨过了获得一些使用以下代码片段输入到 GPG:
~$ stty -echo; gpg2 --edit-key <keyname> "addkey"
但是,运行命令后我无法“管道”输入addkey
。
答案1
2019 年除外,这是你该做的临时主目录:
export GNUPGHOME=$(mktemp -d)
gpg --batch --passphrase '' \
--quick-generate-key "Firstname Lastname <[email protected]>" ed25519 cert 1y
FPR=$(gpg --list-options show-only-fpr-mbox --list-secret-keys | awk '{print $1}')
gpg --batch --passphrase '' \
--quick-add-key $FPR ed25519 sign 1y
gpg --batch --passphrase '' \
--quick-add-key $FPR cv25519 encrypt 1y
类似地,可以添加身份验证子密钥。我们得到:
$ gpg -K
/tmp/tmp.JSOrV6s0iL/pubring.kbx
-------------------------------
sec ed25519 2019-04-11 [C] [expires: 2020-04-10]
7E00D8318E2A2825F40981D00C6CA12AC7F293F3
uid [ultimate] Firstname Lastname <[email protected]>
ssb ed25519 2019-04-11 [S] [expires: 2020-04-10]
ssb cv25519 2019-04-11 [E] [expires: 2020-04-10]
$ gpg --version
gpg (GnuPG) 2.2.12
libgcrypt 1.8.4
答案2
要从gpg2
stdin 读取命令,使用--command-fd=0
。要从gpg2
读取命令的主密钥的密码,使用--pinentry-mode=loopback
。 (gpg2 --help
未列出这些开关,但它们在手册页中有记录。)使用这些开关,您可以gpg2
非交互式地进行通信。
我通过运行类似于以下内容的 bash 命令向现有主密钥添加了一个子密钥:
key=0123456789ABCDEF
passphrase="my passphrase"
{
echo addkey
echo 4 # RSA (sign only)
echo 4096 # key length
echo 0 # key does not expire
echo y # is this correct?
echo y # really create?
echo "$passphrase"
echo save
} | gpg2 --command-fd=0 --status-fd=1 --pinentry-mode=loopback --edit-key $key
答案3
假设您的系统中安装了 expect,并且 ${MY_KEY} 和 ${MY_PASSPHRASE} 设置正确,您可以从此开始。
/usr/bin/expect <<EOF
set timeout 30
spawn gpg --command-fd=0 --status-fd=1 --pinentry-mode=loopback --edit-key ${MY_KEY}
expect {
timeout {send_user "\n!!! timeout !!!\n"; exit 127}
"Bad passphrase*" {exit 127}
"GET_LINE keyedit.prompt*" {send -- "addkey\r"; exp_continue}
"GET_LINE keygen.algo*" {send -- "4\r"; exp_continue}
"GET_LINE keygen.size*" {send -- "4096\r"; exp_continue}
"GET_LINE keygen.valid*" {send -- "0\r"; exp_continue}
"Is this correct?*" {send -- "y\r"; exp_continue}
"Really create?*" {send -- "y\r"; exp_continue}
"KEY_CREATED S*" {send -- "save\r"; exp_continue}
"GET_HIDDEN passphrase.enter*" {send -- "${MY_PASSPHRASE}\r"; exp_continue}
}
set returnvalues [wait]
set exitcode [lindex \$returnvalues 3]
exit \$exitcode
EOF