16

I'm writing a script which creates project archives and then creates 7z archives of them to make it easier on me to save specific versions and keep encrypted backups.

After I've generated the archives and I get to the encryption phase, I'd like to encrypt the files with one call to gpg if possible, so as to only have the user input their passphrase once. Otherwise, we'd either have to cache the user's passphrase in memory (which I'd really like not to do) or have them input and confirm their passphrase for every single project that is archived (which is worse).

Is there a way to pass multiple filenames to gpg to have it encrypt all of them in one go?

If I try this:

$ gpg --cipher-algo AES256 --compression-algo BZIP2 -c project1.7z project2.7z

...I see the following error in the shell:

usage: gpg [options] --symmetric [filename]

Is there a way to do what I'm looking to accomplish?

Naftuli Kay
  • 39,676
  • 2
    Why are you first using 7zip (presumably) to compress, then telling GnuPG to compress again using bzip2? I don't see that gaining you much in terms of space efficiency, and I do see it costing a good deal of CPU. – user May 13 '14 at 20:50
  • 2

    Is there a way to pass multiple filenames to gpg to have it encrypt all of them in one go? Yes, try this answer

    – Anchan Feb 18 '16 at 12:35
  • You can do what you want with just one command, just go to the directory and execute something like this in Windows(cmd) := for /r %i in (*) do "%i" – Allan Registos Apr 16 '21 at 03:09

7 Answers7

13

Since GnuPG doesn't support this directly, the way to do this would be to add another layer, e.g. using tar.

tar c project1.7z project2.7z | gpg --cipher-algo AES256 --compression-algo BZIP2 -co projects.gpg

And to extract:

gpg -d projects.gpg | tar x

You'll be left with project1.7z and project2.7z. Your script can then pick up where you left off.

bahamat
  • 39,666
  • 4
  • 75
  • 104
6
Is there a way to pass multiple filenames to gpg to have it encrypt all of
them in one go?

No, there is not.

You will likely want to pass the passphrase with one of the following gpg options (the latter would be most secure choice):

--passphrase
--passphrase-file
--passphrase-fd
rsaw
  • 1,006
6

Current gpg has an option for this:

gpg --encrypt-files --recipient me@example.com *.txt

produces a .txt.asc file for each .txt file.

References:

3

If you want to try something else then GPG there are other backup methods for encrypting multiple files:

original source: http://www.obsd.hu/docs/Unix-backup-with-aes.txt

vi ~/.bashrc

backup() {
if [[ "$1" = "" ]]; then echo 'specify full path' && exit 1; fi
CURRENTDATE="`date +%F-%Hh`"
echo 'Did you do a screenshot of the Desktop and backup all the Bookmarks of the webbrowser and backup cronjobs, etc...?'
read
echo "START: `date`"
ORIGDIR="$1"; ORIGDIRNORM="`echo $ORIGDIR | sed 's/\/$//g'`"; tar cvf - "${ORIGDIRNORM}/" 2>/dev/null | gzip -9 - 2>/dev/null | openssl aes-256-cbc -salt -out "${ORIGDIRNORM}-backup-${CURRENTDATE}.tar.gz.aes" && cksum "${ORIGDIRNORM}-backup-${CURRENTDATE}.tar.gz.aes" >> checksum.txt
echo "END: `date`"
}

decrypt() {
if [[ "$1" = "" ]]; then echo 'specify full path' && exit 1; fi
CURRENTDATE="`date +%F-%Hh`"
echo 'This will decrypt the backup in the current working directory, are you sure?'
read
echo "START: `date`"
ORIGDIR="$1"
openssl aes-256-cbc -d -salt -in "${ORIGDIR}" | tar -xz -f -
echo "END: `date`"
}

Usage: just use "backup DIRECTORY" for encryption and "decrypt DIRECTORY.tar.gz.aes"

1

Have managed to do something like this, today:

  1. Changed directory to the directory containing the target files, and ran a Bash script to find the required file_names and list them to a text file which I called found.txt.

  2. Ran a Bash script asking gpg2 to read each file name in a loop and into a memory variable, and in the same loop to encrypt it using my signing key and specifying that it was for reading by myself. gpg2 puts up a popup for putting in your pass-phrase, which pop-up has a little check-box where you can opt to keep your pass-phrase active for the session. Bad practice, but not so bad if you are then not on the Net, and you power-down immediately after your encrypting session.

  3. The only problem was that there was a y/n to be handled. So sat with my finger on the Y key and encrypted 51 nos files in less than a minute.


The scripts are given below:

The 'find' script was a file called FindFilesAndListtoTextfile.sh:

#! /usr/bin/bash
#Try this to list the files you want using the appropriate file identifier i.p.o "DSCN.*":

source="/home/myself/Whatever  #note no gaps on either side of the equal-to sign 
 target="/home/myself/Whatever/found.txt"
 find $source -name "*DSCN*" -type f > $target       

The encryption script was called ReadFilenameAndEncrypt.sh:

#!/bin/bash
line="/home/myself/Whatever/found.txt"
while IFS='' read -r line || [[ -n "$line" ]]; do
    echo "Text read from file: $line"
    gpg2 -e -u mysecretkeyID -r mysecretkeyID "$line"
  done < "$1"

This is to be run as a regular user:

$ bash ReadFilenameAndEncrypt.sh found.txt

Hope this helps. Haven't figured out how to avoid the y/n.

oldmud0
  • 103
Aravind
  • 11
0

The following command works for me as long as I do not have any filenames with spaces in them.

for file in $(ls | grep -v ".gpg"); do gpg -c --cipher-algo AES256 --compress-algo 1 --batch --passphrase "<password>" $file && rm -f $file; done

You could also use the find command as well.

for file in $(find /home -type f | grep -v ".gpg"); do gpg -c --cipher-algo AES256 --compress-algo 1 --batch --passphrase "<password>" $file && rm -f $file; done

Lastly if you want to use a file for the password, use:

--passphrase-file <filename>
-1

Yes there is an easy way:

for x in *; do 
  gpg -r (yourencrytionkey.com) -o $x.pgp -e $x
done
slm
  • 369,824