117

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

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

我想检查我正在使用的密码是否实际上是与相应 gpg 密钥关联的密码,但我在 gpg 命令行选项中看不到“不要加密或解密任何东西。只需确认我使用了正确的密码。”

这表明我可能(再次)误解了 Gnu Privacy Guard。(它喜欢嘲弄我直到我哭。)

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

4

4 回答 4

122

没有内置的方法可以做到这一点,但它很简单,可以创建一个不修改任何内容并允许您检查密码的测试。

您没有指定,所以我假设您使用的 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 的某些变体,则该文件可能不存在。-o /dev/null在 Windows 上,您可能只需要通过省略该部分来允许其将签名数据写入屏幕。

接下来,我们使用 指定我们想要进行测试的密钥--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

于 2012-07-14T14:04:57.147 回答
25

这是一个较短的命令行,用于检查密码是否正确:

gpg --export-secret-keys -a <KEYID> > /dev/null && echo OK
于 2019-04-17T21:17:47.900 回答
22

对我来说,检查密码的简单方法是使用gpg --passwd速记。它会尝试更改密码,步骤是确认旧密码,然后您可以在新密码提示上单击“取消”,这样可以保持密码完整。

gpg --passwd <your-user-id>

正如ford04 所说,对于较新版本的 GPG,现在可以将上述命令改进为

gpg --dry-run --passwd <your-user-id>

这是更好的。查看提交

于 2020-05-14T17:11:09.503 回答
5

警告不要使用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

当有效密码被缓存时,下次你运行这个脚本时,它不会要求你输入密码。所以这个脚本可以解决你的问题;“只需确认我使用了正确的密码”

于 2020-08-23T05:05:23.060 回答