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

时间:2012-07-08 06:20:40

标签: gnupg

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

  

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

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

这表明我可能(又一次)误解了Gnu Privacy Guard。 (它倾向于嘲笑我,直到我哭泣。)

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

4 个答案:

答案 0 :(得分:105)

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

您没有指定,因此我假设您使用的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"

首先,管道一些文本与echo "1234" |签署给GnuPG - 因为我们不想签署任何内容,这只是一个测试,所以我们将签署一些无用的文本。

接下来,我们告诉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" - “&amp;&amp;”表示如果上一个命令成功,则打印此消息。为了清楚起见,这只是添加了,因为上面命令的成功否则将完全没有输出。

我希望这很清楚,你可以理解发生了什么,以及如何使用它来做你想做的测试。如果任何部分不清楚或您不理解,我将很乐意澄清。祝你好运!

[编辑] - 如果您使用的是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我们想要运行“批处理”过程,并使用选项--passphrase-fd 1从STDIN(标准输入)中检索密码。

答案 1 :(得分:4)

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

gpg --passwd <your-user-id>

答案 2 :(得分: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

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

答案 3 :(得分:1)

更短的命令行检查密码是否正确

gpg --export-secret-keys -a <KEYID> > /dev/null && echo OK