I am trying to automate backups with duplicity
, but when I test the result, I get
gpg: public key decryption failed: bad passphrase
Warning do not use echo gpg -o /dev/null
as suggested by top answer here. This will cause /dev/null to have invalid permission and corrupting the /dev/null
file. You can verify the /dev/null file's permission when running this command to prove this.
You can use this:
echo "1234" | gpg -q --batch --status-fd 1 --sign --local-user $KEY_ID --passphrase-fd 0 > /dev/null
I also created bash script for this (This one is working with Centos 8). This script will ask for passphrase, if it's invalid, it will keep asking to input valid passphrase. Also if you input wrong or non-existing KEY_ID as an argument it can validate that as well:
#!/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
Sample output if no password is cached in 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:
Sample output if invalid passphrase is entered (it will keep asking):
[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:
Sample output if valid passphrase is entered:
[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
When valid passphrase is cached, the next time you run this script, it will not ask you to enter passphrase. So this script give the solution to your question; "Just confirm I am using the right passphrase"