将第二个子密钥添加到无人值守的 GPG 密钥

将第二个子密钥添加到无人值守的 GPG 密钥

我正在编写一个生成无人值守 GPG 密钥的 bash 脚本,我已经查看过GPG 的无人值守使用并惊讶地发现“目前只能处理一个子项。”

我无法找到是否有办法修改 GPG 密钥以使用可用的无人值守生成功能添加第二个子密钥,或者我是否必须自己手动添加子密钥。

我尝试使用here documentshere 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

诀窍是使用--quick-add-key

类似地,可以添加身份验证子密钥。我们得到:

$ 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

要从gpg2stdin 读取命令,使用--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

相关内容