Как использовать командную строку gpg для проверки правильности парольной фразы

88

Я пытаюсь автоматизировать резервное копирование с помощью duplicity , но когда я проверяю результат, я получаю

gpg: не удалось расшифровать открытый ключ: неверная кодовая фраза

Я хочу проверить, действительно ли используемая мною кодовая фраза является парольной фразой, связанной с соответствующим секретным ключом gpg, но я все равно не вижу в параметрах командной строки gpg сказать «Не шифруйте и не расшифровывайте ничего. Я использую правильную парольную фразу ".

Это говорит о том, что, возможно, я (снова) неправильно понимаю Gnu Privacy Guard. (Он имеет склонность дразнить меня, пока я не заплачу.)

Имеет ли смысл просить gpg проверить кодовую фразу? Если да, то как?

Странное мышление
источник

Ответы:

114

Для этого нет встроенного метода, но достаточно просто создать тест, который ничего не изменяет и позволяет вам просто проверить вашу парольную фразу.

Вы не указали, поэтому я предполагаю, что вы используете версию GnuPG ниже v2 и используете Linux с Bash в качестве интерпретатора командной строки.

Я дам команду здесь, а ниже я объясню, что делает каждая часть - (примечание: следующее относится к серии GnuPG версии 1, см. Ниже для серии GnuPG v2)

echo "1234" | gpg --no-use-agent -o /dev/null --local-user <KEYID> -as - && echo "The correct passphrase was entered for this key"

Что для этого нужно, так это сначала передать какой-то текст для подписи в GnuPG echo "1234" |- потому что мы действительно не хотим ничего подписывать, это всего лишь тест, поэтому мы подпишем какой-то бесполезный текст.

Затем мы говорим gpg не использовать ключевой агент с --no-use-agent ; это важно позже, потому что, в зависимости от вашего ключевого агента, он может не вернуть «0» в случае успеха, и это все, что мы хотим сделать - проверить успешность вашей парольной фразы.

Затем мы говорим gpg поместить подписанные данные непосредственно в /dev/nullфайл, то есть мы отбрасываем их и не записываем результат в терминал - ПРИМЕЧАНИЕ: если вы не используете какой-либо вариант Linux / Unix, этот файл может не существовать. В Windows вам может потребоваться просто разрешить ему записывать подписанные данные на экран, просто опуская-o /dev/null часть.

Затем мы указываем ключ, с которым хотим провести тест, используя --local-user 012345. Вы можете использовать KeyID для максимальной конкретности или использовать имя пользователя, в зависимости от того, что лучше всего соответствует вашим потребностям.

Затем мы указываем -as, что включает режим вывода ascii и устанавливает контекстный режим для подписи. -Потом просто говорит GnuPG , чтобы получить данные , которые должны быть подписаны от стандартного в, который является первой частью команды мы дали echo "1234" |.

И наконец, у нас есть && echo "A message that indicates success" - «&&» означает, что если предыдущая команда была успешной, распечатать это сообщение. Это просто добавлено для ясности, потому что в противном случае успешное выполнение приведенной выше команды означало бы полное отсутствие вывода.

Я надеюсь, что это достаточно ясно, чтобы вы поняли, что происходит, и как вы можете использовать это для тестирования, которое хотите провести. Если какая-то часть непонятна или вы не поняли, буду рад уточнить. Удачи!

[РЕДАКТИРОВАТЬ] - Если вы используете GnuPG v2, приведенную выше команду нужно будет немного изменить, например:

echo "1234" | gpg2 --batch --passphrase-fd 1 -o /dev/null --local-user <KEYID> -as - && echo "The correct passphrase was entered for this key"

Причина в том, что GnuPG v2 ожидает, что кодовая фраза будет получена через агент, поэтому мы не можем отключить использование агента --no-use-agentи получить желаемый эффект; вместо этого нам нужно сообщить GnuPG v2, что мы хотим запустить «пакетный» процесс, и получить кодовую фразу из STDIN (стандартно в) с помощью этой опции --passphrase-fd 1.

Kylehuff
источник
11
Это не работает с gpg2, так как всегда требовался агент. Также агент ncurses каким-то образом сбивается с толку вводом по конвейеру. Так что я просто использовал gpg --local-user <KEYID> -as. Это просто позволяет агенту запрашивать кодовую фразу и сообщать вам, правильна ли она (затем ничего не делает).
BubuIIC
1
Вы, по большей части, правы BubullC; с небольшим изменением переданных параметров вы можете получить аналогичный результат с помощью gpg2. Я изменил свой ответ, чтобы поддержать различия между gpg и gpg2.
kylehuff
4
Попробуйте это для GnuPG 2.1:gpg -o /dev/null --local-user <KEYID> -as <(echo 1234) && echo "The correct passphrase was entered for this key"
starfry
6
Для меня в MacOS 10.12.6 ни один из вариантов не запрашивает парольную фразу и не возвращает сообщение об успешном завершении.
Стэн Джеймс
1
--passphrase-fd 1? читать из stdout? Это работает для меня: gpg2 -aso - <(echo 1234); echo $?. Используйте, echo RELOADAGENT | gpg-connect-agentчтобы забыть парольные фразы.
x-yuri
20

Это более короткая командная строка для проверки правильности парольной фразы:

gpg --export-secret-keys -a <KEYID> > /dev/null && echo OK
Гость
источник
3

Для меня более простой способ проверить парольную фразу - использовать gpg --passwdсокращенную запись. Он пытается изменить парольную фразу, и шаг состоит в том, чтобы подтвердить старую парольную фразу, а затем вы можете щелкнуть «отменить» в запросе новой парольной фразы, и это сохраняет парольную фразу нетронутой.

gpg --passwd <your-user-id>
Лэй Чжао
источник
2

Предупреждение: не используйте эхо, gpg -o /dev/nullкак предлагает верхний ответ здесь. Это приведет к тому, что / dev / null получит недопустимое разрешение и повредит /dev/nullфайл. Вы можете проверить разрешение файла / dev / null при запуске этой команды, чтобы доказать это.

Вы можете использовать это:

echo "1234" | gpg -q --batch --status-fd 1 --sign --local-user $KEY_ID --passphrase-fd 0 > /dev/null

Я также создал для этого сценарий bash (он работает с Centos 8). Этот скрипт будет запрашивать парольную фразу, если она недействительна, он будет продолжать запрашивать правильную парольную фразу. Также, если вы введете неправильный или несуществующий KEY_ID в качестве аргумента, он также может подтвердить это:

#!/bin/bash
# usage ./gpgcron KEYID   | ./gpgcron 2B705B8B6FA943B1
script_path=$(dirname $(realpath -s $0))
script_name=$(basename -- "$0")
GPG_CACHE_BIN="/usr/libexec/gpg-preset-passphrase"
KEY_ID=$1
KEY_GRIP=$(gpg --with-keygrip --list-secret-keys $KEY_ID | grep -Pom1 '^ *Keygrip += +\K.*')
RETVAL=$?
if [[ $RETVAL -ne 0 || -z $KEY_ID ]]; then
    echo "Please provide correct KEY_ID. Example ./$script_name KEY_ID"
    exit 1
fi

export GPG_TTY=$(tty)

function set_gpg_cachepass {
    read -s -p "[$script_name | input]: Enter passphrase to cache into gpg-agent: " PASSPHRASE; echo
    $GPG_CACHE_BIN -c $KEY_GRIP <<< $PASSPHRASE
    RETVAL=$?
    echo "[$script_name | info ]: gpg-preset-passphrase return code: [$RETVAL]"
    if [ $RETVAL = 0 ]; then
        echo "[$script_name | info ]: A passphrase has been set and cached in gpg-agent"
        echo "[$script_name | info ]: Paraphrase set return code: [$RETVAL]"
        gpg_validatepass
    else
        echo "[$script_name | info ]: Unsuccessful error occured: [$RETVAL]"
        set_gpg_cachepass
    fi
}

function gpg_validatepass {
    echo "[$script_name | info ]: Validating passphrase cached in gpg-agent ..."
    echo "1234" | gpg -q --batch --status-fd 1 --sign --local-user $KEY_ID --passphrase-fd 0 > /dev/null
    RETVAL=$?
    if [ $RETVAL = 0 ]; then
        echo "[$script_name | info ]: OK, valid passphrase has been cached in gpg-agent"
    else
        echo "[$script_name | info ]: Warning, invalid passphrase or no passphrase is cached in gpg-agent"
        set_gpg_cachepass
    fi
}

RES=$(echo "KEYINFO --no-ask $KEY_GRIP Err Pmt Des" | gpg-connect-agent | awk '{ print $7 }')
if [ "$RES" == "1" ]; then
    echo "[$script_name | info ]: OK, passphrase is already cached in gpg agent for KEY_ID of [$KEY_ID]"
    gpg_validatepass
else
    echo "[$script_name | info ]: Warning, no passphrase is cached in gpg agent for KEY_ID of [$KEY_ID]"
    set_gpg_cachepass
fi

Пример вывода, если в gpg-agent не кэширован пароль:

[root@earth gpg]# ./gpgcron 2B705B8B6FA943B2
[gpgcron | info ]: Warning, no passphrase is cached in gpg agent for KEY_ID of [2B705B8B6FA943B2]
[gpgcron | input]: Enter passphrase to cache into gpg-agent:

Пример вывода, если введена недопустимая кодовая фраза (запрос будет продолжаться):

[root@earth gpg]# ./gpgcron 2B705B8B6FA943B2
[gpgcron | info ]: OK, passphrase is already cached in gpg agent for KEY_ID of [2B705B8B6FA943B2]
[gpgcron | info ]: Validating passphrase cached in gpg-agent ...
gpg: signing failed: Bad passphrase
gpg: signing failed: Bad passphrase
[gpgcron | info ]: Warning, invalid passphrase or no passphrase is cached in gpg-agent
[gpgcron | input]: Enter passphrase to cache into gpg-agent:

Пример вывода, если введена действительная парольная фраза:

[gpgcron | input]: Enter passphrase to cache into gpg-agent:
[gpgcron | info ]: gpg-preset-passphrase return code: [0]
[gpgcron | info ]: A passphrase has been set and cached in gpg-agent
[gpgcron | info ]: Paraphrase set return code: [0]
[gpgcron | info ]: Validating passphrase cached in gpg-agent ...
[gpgcron | info ]: OK, valid passphrase has been cached in gpg-agent

Когда допустимая кодовая фраза кэшируется, при следующем запуске этого скрипта он не будет запрашивать вас ввести кодовую фразу. Итак, этот скрипт дает решение вашего вопроса; "Просто подтвердите, что я использую правильную кодовую фразу"

MaXi32
источник