Comment utiliser la ligne de commande gpg pour vérifier que la phrase de passe est correcte

88

J'essaie d'automatiser les sauvegardes avec duplicity, mais lorsque je teste le résultat, j'obtiens

gpg: échec du déchiffrement de la clé publique: phrase secrète incorrecte

Je veux vérifier si la phrase de passe que j'utilise est réellement la phrase de passe associée à la clé secrète gpg correspondante, mais je ne vois pas de toute façon dans les options de ligne de commande gpg pour dire "Ne cryptez ou ne décryptez rien. Confirmez simplement J'utilise la bonne phrase de passe. "

Cela suggère que je ne comprends peut-être pas (encore une fois) Gnu Privacy Guard. (Il a une prédilection pour me narguer jusqu'à ce que je pleure.)

Est-il judicieux de demander à gpg de vérifier une phrase de passe? Si c'est le cas, comment?

Pensée étrange
la source

Réponses:

114

Il n'y a pas de méthode intégrée pour faire cela, mais c'est assez simple pour créer un test qui ne modifie rien et vous permet de simplement vérifier votre phrase de passe.

Vous n'avez pas spécifié, donc je suppose que vous utilisez la version GnuPG inférieure à la v2 et que vous êtes sous Linux avec Bash pour votre interpréteur de ligne de commande.

Je vais donner la commande ici et ci-dessous, je vais expliquer ce que fait chaque partie - (note: ce qui suit est pour la série GnuPG version 1, voir ci-dessous pour la série GnuPG v2)

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

Ce que cela fait, c'est d'abord, envoyer du texte à signer à GnuPG echo "1234" |- parce que nous ne voulons vraiment rien signer, c'est juste un test, nous allons donc signer du texte inutile.

Ensuite, nous disons à gpg de ne pas utiliser l'agent clé avec --no-use-agent; ceci est important plus tard car, en fonction de votre agent clé, il peut ne pas retourner "0" en cas de succès, et c'est tout ce que nous voulons faire - vérifier le succès de votre phrase de passe.

Ensuite, nous demandons à gpg de placer les données signées directement dans le /dev/nullfichier, ce qui signifie que nous les supprimons et que nous n'écrivons pas le résultat dans le terminal - REMARQUE: si vous n'utilisez pas une variante de Linux / Unix, ce fichier peut ne pas exister. Sous Windows, vous devrez peut-être simplement lui permettre d'écrire les données signées à l'écran en omettant simplement la -o /dev/nullpartie.

Ensuite, nous spécifions la clé avec laquelle nous voulons faire notre test en utilisant --local-user 012345. Vous pouvez utiliser le KeyID pour une spécificité maximale, ou utiliser un nom d'utilisateur, selon vos besoins.

Ensuite, nous spécifions -as, qui active le mode de sortie ascii et définit le mode de contexte pour la signature. La -suite dit simplement à GnuPG d'obtenir les données à signer à partir de l'entrée standard, qui est la toute première partie de la commande que nous avons donnée echo "1234" |.

Et enfin, nous avons && echo "A message that indicates success"- le "&&" signifie, si la commande précédente a réussi, imprimer ce message. Ceci est juste ajouté pour plus de clarté, car le succès de la commande ci-dessus serait autrement indiqué par aucune sortie du tout.

J'espère que c'est assez clair pour que vous compreniez ce qui se passe et comment vous pouvez l'utiliser pour effectuer les tests que vous souhaitez faire. Si une partie n'est pas claire ou que vous ne comprenez pas, je serai heureux de clarifier. Bonne chance!

[EDIT] - Si vous utilisez GnuPG v2, la commande ci-dessus devra être légèrement modifiée, comme ceci:

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

La raison en est que GnuPG v2 s'attend à ce que la phrase secrète soit récupérée via un agent, nous ne pouvons donc pas désactiver l'utilisation de l'agent avec --no-use-agentet avoir l'effet souhaité; à la place, nous devons dire à GnuPG v2 que nous voulons exécuter un processus "batch", et récupérer la phrase de passe de STDIN (standard in) en utilisant l'option --passphrase-fd 1.

Kylehuff
la source
11
Cela ne fonctionne pas avec gpg2, car il a toujours besoin d'un agent. De plus, l'agent ncurses est en quelque sorte dérouté par l'entrée canalisée. Alors j'ai juste utilisé gpg --local-user <KEYID> -as. Cela permet simplement à l'agent de demander la phrase de passe et de vous dire si elle était correcte (puis ne fait rien).
BubuIIC
1
Vous avez raison BubullC, pour la plupart; avec une légère modification des options passées, vous pouvez obtenir un résultat similaire en utilisant gpg2. J'ai modifié ma réponse pour prendre en charge les différences entre gpg et gpg2.
kylehuff
4
Essayez ceci pour GnuPG 2.1:gpg -o /dev/null --local-user <KEYID> -as <(echo 1234) && echo "The correct passphrase was entered for this key"
starfry
6
Pour moi sur MacOS 10.12.6, aucune des variantes ne demande de mot de passe et renvoie un message de réussite malgré tout.
Stan James
1
--passphrase-fd 1? lire à partir de stdout? Cela fonctionne pour moi: gpg2 -aso - <(echo 1234); echo $?. Utilisez echo RELOADAGENT | gpg-connect-agentpour oublier les mots de passe.
x-yuri
20

Ceci est une ligne de commande plus courte pour vérifier si la phrase de passe est correcte:

gpg --export-secret-keys -a <KEYID> > /dev/null && echo OK
Client
la source
3

Pour moi, la manière simpliste de vérifier la phrase secrète est d'utiliser un gpg --passwdraccourci. Il essaie de changer la phrase de passe et l'étape consiste à confirmer l'ancienne phrase de passe, puis vous pouvez cliquer sur `` Annuler '' sur la nouvelle invite de phrase de passe et cela garde la phrase de passe intacte.

gpg --passwd <your-user-id>
Lei Zhao
la source
2

Attention, n'utilisez pas l'écho gpg -o /dev/nullcomme suggéré par la réponse en haut ici. Cela entraînera / dev / null d'avoir une autorisation invalide et corrompre le /dev/nullfichier. Vous pouvez vérifier l'autorisation du fichier / dev / null lors de l'exécution de cette commande pour le prouver.

Vous pouvez utiliser ceci:

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

J'ai également créé un script bash pour cela (celui-ci fonctionne avec Centos 8). Ce script demandera une phrase de passe, si elle n'est pas valide, il continuera à demander de saisir une phrase de passe valide. De plus, si vous entrez un KEY_ID incorrect ou inexistant en tant qu'argument, il peut également le valider:

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

Exemple de sortie si aucun mot de passe n'est mis en cache dans 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:

Exemple de sortie si une phrase de passe invalide est entrée (elle continuera à demander):

[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:

Exemple de sortie si une phrase de passe valide est entrée:

[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

Lorsqu'une phrase de passe valide est mise en cache, la prochaine fois que vous exécuterez ce script, il ne vous demandera pas de saisir une phrase de passe. Donc ce script donne la solution à votre question; "Confirmez simplement que j'utilise la bonne phrase de passe"

MaXi32
la source