我在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: user@1.com
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
Run Code Online (Sandbox Code Playgroud)
当我运行它时,它显示:
=$ ./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'
Run Code Online (Sandbox Code Playgroud)
但后来它就挂了。
同时,当我检查该用户的 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
Run Code Online (Sandbox Code Playgroud)
在 ~/.gnupg/gpg.conf 中没有提到代理,我不知道它在做什么。
foo.pub/foo.sec 文件在主目录中生成,但为空。
我错过了什么?如何在没有任何用户交互的情况下生成密钥?
版本:
小智 8
我发现只需进行一些简单的更改即可使您的脚本正常工作。我还包含了一些测试,以便一旦创建密钥就会自动对其进行测试。
请注意,与问题中的代码不同,此密钥不受密码保护。
#!/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: user@1.com
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 user@1.com 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 user@1.com keydetails
# Delete the options and decrypt the original to stdout.
rm keydetails
gpg2 -d keydetails.asc
rm keydetails.asc
Run Code Online (Sandbox Code Playgroud)
很可能你的熵已经用完了。密钥生成需要大量非常高质量的随机数;没有用户的活动为计算机提供高质量的随机性,熵池正在被生成耗尽,生成过程只是挂起,等待池重新填充。
你的选择,按照满意度递增的顺序,是
重新配置 gpg 以使用非阻塞伪随机数生成器,这是最不明智的(尽管见下文),
使用软件解决方案从现有系统状态中获取更多熵(众所周知,内核对于准备从系统状态中获取多少熵非常保守,特别是在该状态没有直接人工输入的情况下,例如 CPU 或 NIC 计时);正如您所指出的,haged就是这样一种解决方案,或者
为计算机提供另一种高级熵的物理来源。像Entropy Key或OneRNG这样的设备可以满足这个要求(除了我拥有一个 Entropy Key,我对这两种产品都没有任何联系,并且对它非常满意)。
编辑:mzhaase 在这篇关于 /dev/urandom 与 /dev/random 的文章的评论中引起了我的注意(非常感谢,这是一篇出色的文章!),并提出了我不喜欢使用urandom来创建密钥的问题。事实上,文章并没有说两个来源是等价的,并指出
Linux 的 /dev/urandom 很高兴在内核有机会收集熵之前为您提供不那么随机的数字。那是什么时候?在系统启动时,引导计算机。
也就是说,在启动后,直到urandomPRNG 被初始化为具有足够的熵,使用它来生成密钥确实是不安全的。这可能需要一段时间,尤其是在无人值守的无头服务器上,我们不知道何时达到阈值,因为系统没有明确告诉我们。
现在,如果/dev/random准备发布数字,我可以合理地推断熵池足够深,urandom可以正确初始化。但是,如果我必须/dev/random在每次使用之前检查阻塞urandom(鉴于我生成密钥的频率低于重新启动的频率,很可能是这种情况),我不妨只使用其中的数字/dev/random来生成我的密钥。