Как создать ключ gpg без взаимодействия с пользователем?

Я нашел в https://www.gnupg.org/documentation/manuals/gnupg/Unattended-GPG-key-generation.html метод генерации ключей 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

Когда я запускаю его, он показывает:

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

4 ответа

Решение

Вполне вероятно, что у вас заканчивается энтропия. Генерация ключей требует много очень качественных случайных чисел; без активности пользователя по обеспечению высокого качества случайности компьютера пул энтропии истощается генерацией, а процесс генерации просто зависает, ожидая пополнения пула.

Ваш выбор в порядке увеличения удовлетворенности

  1. реконфигурирование gpg для использования неблокирующего генератора псевдослучайных чисел, что было бы наиболее неразумно (хотя см. ниже),

  2. использование программного решения для получения большей энтропии из существующего состояния системы (ядро общеизвестно консервативно оценивает, какую энтропию оно готово извлечь из состояния системы, особенно когда это состояние не имеет прямого человеческого воздействия, например, времени CPU или NIC); как вы уже указали, есть одно из таких решений:

  3. обеспечение компьютера другим физическим источником полноценной энтропии. Такие устройства, как Entropy Key или OneRNG, могут удовлетворить это требование (я не связан ни с каким продуктом, за исключением того, что у меня есть Entropy Key, и я им очень доволен).

Редактировать: mzhaase обращает мое внимание в комментарии к этой статье на /dev/urandom vs. / dev / random (за что большое спасибо, это отличная статья!) И не соглашается с моей неприязнью к использованию urandom создавать ключи. На самом деле, в статье не говорится, что оба источника эквивалентны, и отмечается, что

Linux /dev/urandom с радостью дает вам не очень случайные числа еще до того, как у ядра появится шанс собрать энтропию. Когда это? При запуске системы, загрузка компьютера.

То есть после загрузки до urandom PRNG был инициализирован с достаточной энтропией, поэтому использовать его для генерации ключей действительно небезопасно. Это может занять некоторое время, особенно на необслуживаемом, безголовом сервере, и мы не знаем, когда был достигнут порог, потому что система явно не сообщает нам.

Сейчас если /dev/random готов выпустить числа, я могу разумно заключить, что энтропийный пул достаточно глубоко, что urandom будет правильно инициализирован. Но если я должен проверить /dev/random для блокировки перед каждым использованием urandom (с учетом того, что я генерирую ключи реже, чем перезагружаюсь, скорее всего, так) Я мог бы просто использовать числа из /dev/random генерировать мои ключи.

Я обнаружил, что есть несколько простых изменений, которые заставят ваш скрипт работать. Я также включил несколько тестов, чтобы после создания ключа он автоматически тестировался.

Я также удалил пароль, чтобы ключевые тесты можно было автоматизировать.

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

# 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

Это было разработано как часть генерации ключей для автоматической установки приложения. Установка и запуск пакета ' rngd' для генерации entroy решит вашу проблему. Прост в установке и использовании.

Вот код

  • Запускает рнгд (/dev/hwrandom по умолчанию, но изменяемый) для обеспечения источника энтропии
  • Копирует простой шаблон поверх (замените электронную почту и имя шаблона jinja на то, что вы хотите)
  • генерирует ключ используя gpg
  • импортирует его в локальный брелок

Вот тот, который вы могли бы использовать, но я бы порекомендовал запустить этот скрипт в новом терминале, чтобы он не влиял на ваш текущий. Этот сценарий будет продолжать генерировать энтропию, оставляя машину занятой и зацикливаясь на бесконечном цикле, пока пользователь не закроет сценарий. Взаимодействие с пользователем не требуется до генерации ключа. Все, что делает скрипт - это список файлов навсегда.

Генерирование может занять несколько минут (иногда более 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
Другие вопросы по тегам