22

I found in https://www.gnupg.org/documentation/manuals/gnupg/Unattended-GPG-key-generation.html#Unattended-GPG-key-generation method to generate gpg keys without user interaction, but it doesn't seem to work.

My script is:

#!/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

When I run it, it shows:

=$ ./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'

But then it just hangs.

When I check, in the mean time, ps tree for this user, I see:

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

In ~/.gnupg/gpg.conf there is no mention about agent, and I have no idea what it's trying to do.

The foo.pub/foo.sec files are generated in home dir, but are empty.

What am I missing? How to generate the key without any kind of user interaction?

Versions:

  • gpg (GnuPG) 2.0.26
  • libgcrypt 1.6.2

4 Answers 4

7

It is likely that you are running out of entropy. Key generation requires a lot of very high-quality random numbers; without the activity of the user to provide high-quality randomness to the computer, the entropy pool is being exhausted by generation, and the generation process just hangs, waiting for the pool to refill.

Your choices, in order of increasing satisfactoriness, are

  1. reconfiguring gpg to use the non-blocking pseudorandom number generator, which would be most unwise (though see below),

  2. using a software solution to derive more entropy from existing system state (the kernel is notoriously conservative about how much entropy it is prepared to derive from system state, particularly where that state has no direct human input, eg CPU or NIC timings); as you have pointed out, haveged is one such solution, or

  3. providing the computer with another physical source of high-grade entropy. Devices like the Entropy Key or the OneRNG can satisfy this requirement (I have no connection with either product save that I own an Entropy Key, and am very happy with it).

Edit: mzhaase draws my attention in a comment to this article on /dev/urandom vs. /dev/random (for which many thanks, it is an excellent article!) and takes issue with my dislike of using urandom to create keys. In fact, the article does not say that the two sources are equivalent, and notes that

Linux's /dev/urandom happily gives you not-so-random numbers before the kernel even had the chance to gather entropy. When is that? At system start, booting the computer.

That is to say that, after boot, until the urandom PRNG has been initialised with sufficient entropy, it really is unsafe to use it for key generation. That may take a while, especially on an unattended, headless server, and we don't know when the threshold has been reached, because the system doesn't explicitly tell us.

Now, if /dev/random is prepared to issue numbers I may reasonably infer that the entropy pool is deep enough that urandom will have been properly initialised. But if I have to check /dev/random for blocking before each use of urandom (which given that I generate keys less often than I reboot, is likely to be the case) I might as well just use the numbers from /dev/random to generate my keys.

5
  • 2
    That is/was the problem. Added haveged daemon, and now it works fine - key generation in ~ 0.7s.
    – eijeze
    May 11, 2015 at 14:40
  • 1
    That PRNGs are not 'as good' is a myth. In fact both /dev/random and /dev/urandom use the same PRNG. You do not require true randomness for algorithms which are only computationally secure (and neither /dev/random nor /dev/urandom can actually give you true randomness: you need to measure actually random things for that). The only cryptography that requires true randomness are informationally secure algorithms like the one-time-pad. This link talks about this in detail: 2uo.de/myths-about-urandom
    – mzhaase
    Aug 9, 2016 at 14:25
  • 1
    @mzhaase oddly, I came across that link, and read it, earlier this week. I'll edit my answer above to reflect the article, though I don't entirely agree with it. I also note that my system, oddly, probably does get true randomness from /dev/random, (and therefore highly-unpredictable numbers from /dev/urandom nearly all the time), because I have a hardware device which uses quantum tunneling to generate entropy physically attached to my server (see above).
    – MadHatter
    Aug 10, 2016 at 6:42
  • 1
    haveged works nice, key is generated in 1 sec. Just apt-get install haveged , and then run: haveged
    – jmp
    May 25, 2017 at 8:49
  • 1
    @waza123 good point, though arguably one that was already made by eijeze two years before (look at the first comment above).
    – MadHatter
    May 25, 2017 at 11:46
5

I found there are a few simple changes that make your script work. I have also included a few tests so that once the key is created it will automatically be tested.

Note that, unlike the code in the question, this key is not password protected.

#!/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
2
  • Thank you very much! this saved me a lot of time on researching... Great thanks!
    – wei
    Aug 17, 2021 at 7:02
  • I changed the key from 2048 to 4096 and it prompts for password. is there a way to increase this value.
    – MaXi32
    Sep 4, 2021 at 15:09
0

Worked this out as part of generating keys for an automated application install. Installing and starting the 'rngd' package to generate entroy will fix your issue. Simple to install and use.

Here's the code.

  • Starts rngd (/dev/hwrandom by default, but modifiable) to provide a source of entropy
  • Copies a simple template over (replace the jinja template email and name with what you want)
  • generates a key using gpg
  • imports it to the local keyring
3
  • In the sample code provided urandom is used as a source, that is discouraged. wiki.archlinux.org/index.php/Rng-tools Warning: Some tutorials available in the Internet, and even early versions of rng-tools package, recommend the following line for systems without TRGN: RNGD_OPTS="-o /dev/random -r /dev/urandom" Of course, this is a really bad idea, since you are simple filling the kernel entropy pool with entropy coming from the kernel itself! If your system does not have an available TRGN consider using haveged instead. See FS#34580 for details.
    – keyneom
    Feb 13, 2016 at 19:42
  • @keyneom rngd uses /dev/hwrandom by default and is modifiable. See man page.
    – xddsg
    Aug 9, 2016 at 14:04
  • Right, I was stating that in the code you linked to it is explicitly using urandom and that doing so is discouraged.
    – keyneom
    Aug 13, 2016 at 15:30
-1

Here is one you could use but I would recommend running this script in a new terminal so as to not affect your current one. This script will continue to generate entropy by keeping the machine busy and stuck in an infinite loop until a user exits the script. No user interaction is necessary until after key generation. All the script does is list files forever.

It might take a few minutes (sometimes 10+) to generate depending on your machine and size of key but it is nice to not have to interact with it.

#!/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
1
  • Doing a find on a filesystem is not generating a truly secure source of entropy because its behavior is predictable and reproducible.
    – Joffrey
    Dec 9, 2018 at 0:45

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.