如何使用gpg命令行检查密码是否正确


88

我正在尝试使用来自动执行备份duplicity,但是当我测试结果时,我得到了

gpg:公钥解密失败:密码短语错误

我想检查我使用的密码短语是否实际上是与相应gpg密钥相关联的密码短语,但是无论如何我都无法在gpg命令行选项中看到“不要加密或解密任何内容。只需确认我使用的密码正确。”

这表明也许我(还是再次)误解了Gnu Privacy Guard。(它偏向嘲弄我直到我哭泣。)

要求gpg验证密码是否有意义?如果是这样,怎么办?

Answers:


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不要将key agent与--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我们要运行“批处理”过程,并使用option从STDIN(标准输入)中检索密码--passphrase-fd 1


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"
2016年

6
对于我来说,在MacOS 10.12.6上,任何版本都不会提示输入口令,无论如何都不会返回成功消息。
斯坦·詹姆斯

1
--passphrase-fd 1?从标准输出读取?这对我的作品: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按照此处的最高答案的建议使用echo 。这将导致/ 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

当高速缓存有效密码短语时,下次运行此脚本时,它将不会要求您输入密码短语。因此,该脚本为您的问题提供了解决方案;“只需确认我使用的密码正确”

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.