How to fix "no valid OpenPGP data found" after piping gpg with "--status-id 1" to a file - gnupg

I have a script that uses gpg to encrypt a file and upload it to Google Drive:
cat backup.tar.gz \
| gpg --symmetric --batch --status-fd 1 --with-colons --cipher-algo AES256 --passphrase ${5} \
| gdrive upload - backup.tar.gz.gpg
When trying to decrypt backup.tar.gz.gpg:
gpg backup.tar.gz.gpg
I get this error:
gpg: no valid OpenPGP data found.
gpg: processing message failed: Unknown system error
I think the problem is in using --status-fd 1.
Can anybody advice how to decrypt this existing file?

Related

Programmatically verify checksum using gpg format

I would like to programmatically validate the sha512 checksum of a Kafka binary. First I download the binary and the sha512 sum text file:
curl -fsSL -O \
https://ftp.wayne.edu/apache/kafka/2.7.0/kafka_2.13-2.7.0.tgz
curl -fsSL -O \
https://downloads.apache.org/kafka/2.7.0/kafka_2.13-2.7.0.tgz.sha512
I know by manual inspection that the checksum is ok:
$ cat -ne kafka_2.13-2.7.0.tgz.sha512
1 kafka_2.13-2.7.0.tgz: F3DD1FD8 8766D915 0D3D395B 285BFA75 F5B89A83 58223814$
2 90C8428E 6E568889 054DDB5F ADA1EB63 613A6441 989151BC$
3 7C7D6CDE 16A871C6 674B909C 4EDD4E28$
$ sha512sum kafka_2.13-2.7.0.tgz
f3dd1fd88766d9150d3d395b285bfa75f5b89a835822381490c8428e6e568889054ddb5fada1eb63613a6441989151bc7c7d6cde16a871c6674b909c4edd4e28 kafka_2.13-2.7.0.tgz
But shasum/sha512sum don't seem to like the format of the .512 file to do programatic validation (0 exit code on success, 1 on failure).
$ sha512sum --check kafka_2.13-2.7.0.tgz.sha512
sha512sum: kafka_2.13-2.7.0.tgz.sha512: no properly formatted SHA512 checksum lines found
$ echo "$(cat kafka_2.13-2.7.0.tgz.sha512) kafka_2.13-2.7.0.tgz" \
| sha512sum --check
sha512sum: 'standard input': no properly formatted SHA512 checksum lines found
What do I have wrong here? Is kafka_2.13-2.7.0.tgz.sha512 in an unconventional format or am I missing a command line flag?
Seems like kafka is using gpg --print-md sha512 https://github.com/apache/kafka/blob/trunk/release.py#L616
Verification is done by diff then
$ gpg --print-md SHA512 kafka_2.13-2.7.0.tgz | diff - kafka_2.13-2.7.0.tgz.sha512
http://people.apache.org/~ke4qqq/ig/sect-source-verify.html

How to send the password automatically in gpg's symmetric encryption?

I want to make a symmetric encryption for the file /tmp/public.txt.
gpg --symmetric /tmp/public.txt
The command will invoke the enter passphrase window,i want to send the password automatically.
My try here:
echo "mylongpasswordhere" | gpg --passphrase-fd 0 --symmetric /tmp/public.txt
The enter passphrase window still pop up, How to send the password automatically in gpg's symmetric encryption ?
Since I stumbled on this question having the same problem, I'll post the answer that actually helped me (from other SE question). The key options here are --batch --yes:
$ gpg --passphrase hunter2 --batch --yes --symmetric file_to_enc
(Taken from this question )
That way you can actually encrypt a file symmetrically supplying the key as commandline argument, although this might mean that other users of the system might see the passphrase used.
Depending on your GnuPG version (>= 2.1.0 ) you need to add "--pinentry-mode loopback" to the command.
For GnuPG version >= 2.1.0 but < 2.1.12 you also need to add: "allow-loopback-pinentry" to the ~/.gnupg/gpg-agent.conf
Your command would then be:
echo "mylongpasswordhere" | gpg --pinentry-mode loopback --passphrase-fd 0 --symmetric /tmp/public.txt
Alternatively you don't have to use passphrase-fd and the echo but can directly provide the passphrase:
gpg --pinentry-mode loopback --passphrase "somepass" --symmetric /tmp/public.txt
key="it is a long password to encrypt and decrypt my file in symmetric encryption
"
Encypt public.txt.
openssl enc -des3 -a -salt -in public.txt -k ${key} -out public.asc
Decrypt public.asc.
openssl enc -d -des3 -a -salt -k ${key} -in public.asc -out public.out
Can i draw a conclusion that openssl is a more powerful tool for encryption than gpg?

Why can't I run gpg in non-interactive mode successfully?

I'm writing a script that uses gpg to encrypt a file. During testing/experimentation with gpg from the command-line, I found some odd behavior. This works perfectly fine:
$ cat myFile.txt | gpg --encrypt -r 'jdoe#gmail.com'
gpg: B2D17635: There is no assurance this key belongs to the named user
pub 4096R/B2D17635 2016-01-31 John Doe (I am now a real person.) <jdoe#gmail.com>
Primary key fingerprint: B17F 98BA 1DA9 3FE1 A08F 1443 509D 87ED 32AF 2078
Subkey fingerprint: BB63 42DA 8FAD 194A E1C9 1F6D 39BA 73B9 B2D1 7635
It is NOT certain that the key belongs to the person named
in the user ID. If you *really* know what you are doing,
you may answer the next question with yes.
Use this key anyway? (y/N) y
�
Nϴ��[�mDZ.#�Bc���J������z�{p���%
<GIBBERISH SNIPPED>
i�)��/&N��t�Z�8�#�I<�Bq�!�K?�vQ�I�H6&+��(
But I don’t like that because I interactively had to type ‘y’. I would like it to assume “yes” and do the encryption without requiring any interactivity. So I ran the following command with the --batch and --yes switches. Why did it fail?
$ cat myFile.txt | gpg --encrypt --batch --yes -r 'jdoe#gmail.com'
gpg: B2D17635: There is no assurance this key belongs to the named user
gpg: [stdin]: encryption failed: unusable public key
The error you're receiving from GnuPG is because the public key isn't trusted/verified within your keyring. Because your OP stated that your running tests you may want to check out the code within a helper script written for my own experiments, GnuPG_Gen_Key.sh, specifically the functions copied/modded below.
#!/usr/bin/env bash
Var_gnupg_import_key="${1}"
Var_gnupg_import_key_trust="${2}"
Func_import_gnupg_key_edit_trust(){
_gnupg_import_key="${1:-${Var_gnupg_import_key}}"
gpg --no-tty --command-fd 0 --edit-key ${_gnupg_import_key} <<EOF
trust
${Var_gnupg_import_key_trust}
quit
EOF
}
Func_import_gnupg_key(){
_gnupg_import_key="${1:-${Var_gnupg_import_key}}"
if [ -f "${_gnupg_import_key}" ]; then
echo "# ${Var_script_name} reports: importing key file [${_gnupg_import_key}]"
gpg --no-tty --command-fd 0 --import ${_gnupg_import_key} <<EOF
trust
${Var_gnupg_import_key_trust}
quit
EOF
else
_grep_string='not found on keyserver'
gpg --dry-run --batch --search-keys ${_gnupg_import_key} --keyserver ${Var_gnupg_key_server} | grep -qE "${_grep_string}"
_exit_status=$?
if [ "${_exit_status}" != "0" ]; then
_key_fingerprint="$(gpg --no-tty --batch --dry-run --search-keys ${_gnupg_import_key} | awk '/key /{print $5}' | tail -n1)"
_key_fingerprint="${_key_fingerprint//,/}"
if [ "${#_key_fingerprint}" != "0" ]; then
echo "# ${Var_script_name} reports: importing key [${_key_fingerprint}] from keyserver [${Var_gnupg_key_server}]"
gpg --keyserver ${Var_gnupg_key_server} --recv-keys ${_key_fingerprint}
Func_import_gnupg_key_edit_trust "${_gnupg_import_key}"
else
echo "# ${Var_script_name} reports: error no public key [${_gnupg_import_key}] as file or on key server [${Var_gnupg_key_server}]"
fi
else
echo "# ${Var_script_name} reports: error no public key [${_gnupg_import_key}] as file or on key server [${Var_gnupg_key_server}]"
fi
fi
}
One can either trust the public key with above or use the following command to have GnuPG ignore trust issues.
gpg --armor --always-trust -r 'jdoe#gmail.com' -e myFile.txt -o myFile.txt.gpg
Note I've added the --armor option because the output in the OP looks to have missed that based off the snipped output.
You have to add --always-trust to your command:
echo "test" | gpg --batch --yes --always-trust --encrypt --armor -r "mail#example.com"
Probably better than using --always-trust is to sign the keys your are relying on once with your private key.
Then gpg won't ask again.
Also you encrypted standard input, so the ciphertext will be sent to standard output.
In most cases you want to use option --armor to produce ASCII output.

decrypt multiple OpenPGP files in a directory

I have several hundred gpg encrypted files in a directory, of the format filename.xyz.gpg where "xyz" is some arbitrary extension. I need to decrypt all of the files to generate filename.xyz decrypted in such a way that I don't have to manually enter the password for each file.
I have tried the following for directory "Testing":
for file in 'ls Testing'; do (echo <password>|gpg --passphrase-fd 0 -d $file
--output $file.decrypted);
I just wind up with a command prompt >, and nothing happens.
What is the matter with my syntax? Is there some more efficient way to do this without a bash shell loop?
gpg can decrypt multiple files so you shouldn't need to write a loop.
Try the following. You will need to enter your password once.
gpg --passphrase-fd 0 --decrypt-files *.gpg
As it is said in the manual you need to add --batch option:
--passphrase-fd n
Read the passphrase from file descriptor n. Only the first line will be read from file descriptor n. If you use 0 for n, the passphrase will be read from
STDIN. This can only be used if only one passphrase is supplied. Note that this passphrase is only used if the option --batch has also been given. This is
different from gpg.
--passphrase string
Use string as the passphrase. This can only be used if only one passphrase is supplied. Obviously, this is of very questionable security on a multi-user sys‐
tem. Don't use this option if you can avoid it. Note that this passphrase is only used if the option --batch has also been given. This is different from
gpg.
You can have either of these two forms:
echo "passphrase" | gpg --passphrase-fd 0 --batch -d --output "decrypted.file" "file.gpg"
Or simpler:
gpg --passphrase "passphrase" --batch -d --output "decrypted.file" "file.gpg"
You can try a script like this to extract your files:
#!/bin/bash
read -rsp "Enter passphrase: " PASSPHRASE
for FILE in *.*.gpg; do
echo "Extracting $FILE to ${FILE%.gpg}."
echo "$PASSPHRASE" | gpg --passphrase-fd 0 --batch -d --output "${FILE%.gpg}" "$FILE"
done
I had success with
gpg --decrypt-files *.gpg
cf. https://serverfault.com/a/388068/103585
I had success with gpg --decrypt-files *
but not *.gpg
It worked with below commands for me:
For single file:
gpg --decrypt --input C:\PGPFiles\[encryptedfilename.pgp] --passphrase [yourpassphrase]
For multiple files:
gpg --decrypt --input C:\PGPFiles\* --passphrase [yourpassphrase]

Writing gpg decrypted file to a specified outfile

I attempted to decrypt an encrypted gpg file using:
gpg -d <encrypted file> --output <outfile>
and just get a message:
usage: gpg [options] --decrypt [filename]
In contrast, if I use
gpg -d <encrypted file>
the file is decrypted, but it's written to a default file and displayed to the terminal screen. The former isn't a big issue, but the latter (display in terminal screen while decrypting) is a real nuisance. What, if anything, can be done about it?
Try gpg --output <outfile> -d <encrypted file>
The "-d" is unnecessary, this is fine:
gpg -o plaintext.txt ciphertext.asc
As for printing the decypted data to stdout, that usually only happens when the sender uses the old "for-your-eyes-only" flag. To determine exactly what is happening there, though, I'd need more detail on the version of GPG in use and possibly some information on the ciphertext.

Resources