如何在没有用户交互的情况下生成 gpg 密钥?

如何在没有用户交互的情况下生成 gpg 密钥?

我发现https://www.gnupg.org/documentation/manuals/gnupg/Unattended-GPG-key-generation.html#Unattended-GPG-key-generation无需用户交互即可生成 gpg 密钥的方法,但它似乎不起作用。

我的脚本是:

#!/usr/bin/env bash
rm -rf .gnupg
mkdir -m 0700 .gnupg
touch .gnupg/gpg.conf
chmod 600 .gnupg/gpg.conf
tail -n +4 /usr/share/gnupg2/gpg-conf.skel > .gnupg/gpg.conf

touch .gnupg/{pub,sec}ring.gpg


cat >.gnupg/foo <<EOF
    %echo Generating a basic OpenPGP key
    Key-Type: RSA
    Key-Length: 2048
    Subkey-Type: RSA
    Subkey-Length: 2048
    Name-Real: User 1
    Name-Comment: User 1
    Name-Email: [email protected]
    Expire-Date: 0
    Passphrase: kljfhslfjkhsaljkhsdflgjkhsd
    %pubring foo.pub
    %secring foo.sec
    # Do a commit here, so that we can later print "done" :-)
    %commit
    %echo done
EOF

gpg2 --verbose --batch --gen-key .gnupg/foo

当我运行它时,它显示:

=$ ./gen.keys.sh 
gpg: Generating a basic OpenPGP key
gpg: no running gpg-agent - starting one
gpg: writing public key to `foo.pub'
gpg: writing secret key to `foo.sec'

但之后它就挂了。

同时,当我检查该用户的 ps 树时,我看到:

USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
tstpg    22603  0.0  0.0  24108  5688 pts/9    Ss   14:59   0:00 -bash
tstpg    22624  0.0  0.0  13688  3168 pts/9    S+   14:59   0:00  \_ bash ./gen.keys.sh
tstpg    22632  0.2  0.0  27428  3676 pts/9    SL+  14:59   0:00      \_ gpg2 --verbose --batch --gen-key .gnupg/foo
tstpg    22634  0.3  0.0  18072  2884 pts/9    SL+  14:59   0:00          \_ gpg-agent --server

在 ~/.gnupg/gpg.conf 中没有提到代理,我不知道它想要做什么。

foo.pub/foo.sec 文件在主目录中生成,但是是空的。

我错过了什么?如何在没有任何用户交互的情况下生成密钥?

版本:

  • gpg(GnuPG)2.0.26
  • libgcrypt 1.6.2

答案1

很可能您的熵已经耗尽。密钥生成需要大量非常高质量的随机数;如果没有用户向计算机提供高质量随机性,熵池就会因生成而耗尽,生成过程就会挂起,等待池子重新填充。

按照满意度的增加顺序,您的选择是

  1. 重新配置 gpg 以使用非阻塞伪随机数生成器,这是最不明智的(见下文)

  2. 使用软件解决方案从现有系统状态中获取更多熵(众所周知,内核对于从系统状态中获取多少熵非常保守,特别是在该状态没有直接的人为输入的情况下,例如 CPU 或 NIC 时序);正如你所指出的,哈格德就是这样的一个解决方案,或者

  3. 为计算机提供了另一个高级熵的物理来源。像熵密钥或者OneRNG可以满足这个要求(我与这两种产品都没有任何联系,除了我拥有一个 Entropy Key,并且对它非常满意)。

编辑:mzhaase 在评论中引起了我的注意这篇关于 /dev/urandom 与 /dev/random 的文章(非常感谢,这是一篇很棒的文章!)并对我不喜欢使用urandom来创建密钥提出异议。事实上,这篇文章并没有说这两个来源是等价的,并指出

Linux 的 /dev/urandom 会在内核有机会收集熵之前就高兴地为您提供非随机数。那是什么时候?在系统启动时,启动计算机。

也就是说,启动后,直到 PRNGurandom初始化为具有足够熵之前,使用它来生成密钥确实是不安全的。这可能需要一段时间,尤其是在无人值守的无头服务器上,而且我们不知道何时达到阈值,因为系统没有明确告诉我们。

现在,如果/dev/random准备发出数字,我可以合理地推断熵池足够深,urandom已经正确初始化。但如果我必须/dev/random在每次使用之前检查阻塞urandom(鉴于我生成密钥的频率低于重新启动的频率,很可能是这种情况),我不妨只使用来自的数字/dev/random来生成我的密钥。

答案2

我发现只需进行一些简单的更改即可让您的脚本正常运行。我还添加了一些测试,这样一旦创建了密钥,它就会自动进行测试。

请注意,与问题中的代码不同,此密钥不受密码保护

#!/usr/bin/env bash
rm -rf .gnupg
mkdir -m 0700 .gnupg
touch .gnupg/gpg.conf
chmod 600 .gnupg/gpg.conf
tail -n +4 /usr/share/gnupg2/gpg-conf.skel > .gnupg/gpg.conf

cd .gnupg
# I removed this line since these are created if a list key is done.
# touch .gnupg/{pub,sec}ring.gpg
gpg2 --list-keys


cat >keydetails <<EOF
    %echo Generating a basic OpenPGP key
    Key-Type: RSA
    Key-Length: 2048
    Subkey-Type: RSA
    Subkey-Length: 2048
    Name-Real: User 1
    Name-Comment: User 1
    Name-Email: [email protected]
    Expire-Date: 0
    %no-ask-passphrase
    %no-protection
    %pubring pubring.kbx
    %secring trustdb.gpg
    # Do a commit here, so that we can later print "done" :-)
    %commit
    %echo done
EOF

gpg2 --verbose --batch --gen-key keydetails

# Set trust to 5 for the key so we can encrypt without prompt.
echo -e "5\ny\n" |  gpg2 --command-fd 0 --expert --edit-key [email protected] trust;

# Test that the key was created and the permission the trust was set.
gpg2 --list-keys

# Test the key can encrypt and decrypt.
gpg2 -e -a -r [email protected] keydetails

# Delete the options and decrypt the original to stdout.
rm keydetails
gpg2 -d keydetails.asc
rm keydetails.asc

答案3

将此作为自动应用程序安装生成密钥的一部分。安装并启动'随机数生成器' 生成 entroy 的包将解决您的问题。安装和使用都很简单。

以下是代码

  • 启动 rngd(/dev/hwrandom默认,但可修改)以提供熵源
  • 复制一个简单的模板(将 jinja 模板电子邮件和名称替换为您所需的)
  • 使用 gpg 生成密钥
  • 将其导入到本地密钥环

答案4

你可以使用这个脚本,但我建议在新的终端中运行这个脚本,以免影响你当前的终端。这个脚本将通过保持机器忙碌并陷入无限循环来继续生成熵,直到用户退出脚本。在密钥生成之前不需要用户交互。脚本所做的只是永远列出文件。

根据您的机器和密钥大小,生成可能需要几分钟(有时 10 分钟以上),但最好不需要与它交互。

#!/bin/sh

while true;
do find * / && find * / && find * / && find * / && find * / && find * / && find * / && find * / && find * /;

echo "Press ctrl+c to exit this infinite loop"
sleep 2;
done

相关内容